home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacTech 1 to 12
/
MacTech-vol-1-12.toast
/
Reference
/
the cmsp digests ('94-'97)
/
csmp digest Vol 3 No 049
< prev
next >
Wrap
Internet Message Format
|
1997-05-06
|
113KB
From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-049
Date: Mon, 8 Aug 1994 16:13:56 +0200 (MET DST)
C.S.M.P. Digest Mon, 08 Aug 94 Volume 3 : Issue 49
Today's Topics:
CODE resources 101
Can I do this with the Thread Manager?
Dice Rolling - answers
Easy file access functions [source]
How to detect whether Debugger is installed?
Q: Converting PB to FSSpec
Q: Reentrancy and PowerMac Runtime Model
Std filter proc trashes register D3!
Which NIM for serial port info?
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.
Also, the digests are available to WAIS users. To search back issues
with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-------------------------------------------------------
>From ikb_macd@ECE.Concordia.CA (Keith MacDonald)
Subject: CODE resources 101
Date: Fri, 15 Jul 1994 05:30:50 GMT
Organization: ECE - Concordia University
I'd like to be able to distribute files (aka plug-ins) to add features
to a program I'm working on. These files would (I assume) contain code
resources. I've not been able to find any examples or clear description
of what I need to do to achieve this. I'm using Pascal, but I imagine
C works in a similar manner.
Also related to code resources -
would it be possible to have a C PPC native code resource used by
a non-native (written in Think Pascal) application?
Thanks,
Keith
..............................................................................
Keith MacDonald A bridge is not a high place
ikb_macd@ece.concordia.ca The fifty-second floor
Computer Engineering Icarus would know
Concordia University A mountain isn't far to fall
Montreal, QC, CANADA When you've fallen from the moon
- Marillion
+++++++++++++++++++++++++++
>From mathews@ns9000.furman.edu (Owen Mathews)
Date: 15 Jul 1994 17:03:44 GMT
Organization: furman university computing center
Keith MacDonald (ikb_macd@ECE.Concordia.CA) wrote:
: I'd like to be able to distribute files (aka plug-ins) to add features
: to a program I'm working on. These files would (I assume) contain code
: resources. I've not been able to find any examples or clear description
: of what I need to do to achieve this. I'm using Pascal, but I imagine
: C works in a similar manner.
: Also related to code resources -
: would it be possible to have a C PPC native code resource used by
: a non-native (written in Think Pascal) application?
Using code resources to add functionality to an existing program doesn't
require too much modification. You can "call" a code resource just like
calling a function (see code example below). The main concept to under-
stand is that code resources can be compiled from souce files just as
an application can be. The compiler should let you do this when you are
setting all of the options for compiling and linking (in SC++, the menu
option is "Set Project Type"). When the resource is called, the entry
point is simply the main procedure of the file.
For more info, see IM.
********************this code example was taken from
********************Think Reference, copyright Symantec corp.
// Calling a Code Resource
// The following code illustrates how to call a
// code resource. The code resource that we
// are calling is given at the end
// Assuming inclusion of <MacHeaders>
typedef void (*MyProcPtr) (int); // Define a procedure pointer
// for the code resource
void DoError (OSErr err);
main ()
{
Handle myCRHandle;
ProcPtr myCRPtr;
int integerParam;
myCRHandle = GetNamedResource ('ALCT', "\pmyBeep");
if (myCRHandle == nil)
DoError (ResError());
else
{
HLock (myCRHandle);
(* (MyProcPtr) (*myCRHandle)) (integerParam);
HUnlock (myCRHandle);
}
}
/*********************************************
Here is the code resource that we're calling
void main (int i)
{
int j;
for (j = 0; j < i; j++)
SysBeep (5);
}
**********************************************/
: Also related to code resources -
: would it be possible to have a C PPC native code resource used by
: a non-native (written in Think Pascal) application?
PPC macs do not use the same kind of CODE resources that 68k macs do.
Instead of keeping their program code in the resource fork, divided into
32K segments, PowerMacs keep code in the *data* fork of a file. It may
be possible to call a PPC code chunk from a Pascal application (using the
mixed-mode manager), but it will be a little different than calling a
68k code resource.
--
Owen Mathews mathews@furman.edu
<><><><><><><><><><><><><><><><><><><><>
Furman University, Computer Science Dept
+++++++++++++++++++++++++++
>From tyen@netcom.com (Anthony Yen)
Date: Sat, 16 Jul 1994 09:13:13 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
In article <306fhg$fl8@ns9000.furman.edu>,
Owen Mathews <mathews@ns9000.furman.edu> wrote:
>PPC macs do not use the same kind of CODE resources that 68k macs do.
>Instead of keeping their program code in the resource fork, divided into
>32K segments, PowerMacs keep code in the *data* fork of a file. It may
>be possible to call a PPC code chunk from a Pascal application (using the
>mixed-mode manager), but it will be a little different than calling a
>68k code resource.
Hmm...several questions come to mind as I read this:
Has anyone seen how to support calling PPC-native code from within a
PPC-native app? And from within a fat-app?
If I append some application-specific data to the data fork of a
fat-app, it won't confuse the loader or whatever else Apple might have
in store for the data fork in the future, right? <hope, hope, cross
fingers>
Is there a convention for writing fat-code? That is, can I just build
a CODE resource for 68K, then do what I normally do to build a fat-app
but wave the magic wand over the CODE resource instead, and append the
PPC code onto that resource file and wind up with a fat-loadable code
module? If I can, is there a single calling convention for both
loadable code modules (this refers back to my first question)?
Finally, the THINK Reference code sample appears to add two
dereferences over the standard function call overhead when calling a
code resource. Is this correct? If it is correct, in the grand
scheme of things this would not matter, but I may get down to shaving
cycles in the future and if so I may need to have all code resources
locked down in memory and as fully dereferenced as possible. Offhand,
I see only one dereference I could avoid, by making sure the code
resource is marked locked and getting a pointer out of the handle.
But I'm getting a nagging feeling I'm missing something here...
--
Anthony Yen <tyen@netcom.com> Austin, Texas, USA
+++++++++++++++++++++++++++
>From jwbaxter@olympus.net (John W. Baxter)
Date: Sat, 16 Jul 1994 10:03:43 -0700
Organization: Internet for the Olympic Peninsula
In article <tyenCt10A2.CsB@netcom.com>, tyen@netcom.com (Anthony Yen) wrote:
> In article <306fhg$fl8@ns9000.furman.edu>,
> Owen Mathews <mathews@ns9000.furman.edu> wrote:
> >PPC macs do not use the same kind of CODE resources that 68k macs do.
> >Instead of keeping their program code in the resource fork, divided into
> >32K segments, PowerMacs keep code in the *data* fork of a file. It may
> >be possible to call a PPC code chunk from a Pascal application (using the
> >mixed-mode manager), but it will be a little different than calling a
> >68k code resource.
>
> Hmm...several questions come to mind as I read this:
>
> Has anyone seen how to support calling PPC-native code from within a
> PPC-native app? And from within a fat-app?
Widely available for some time now.
Inside Mac: PowerPC System Software
various "develop" articles
various "MacTech" articles
> If I append some application-specific data to the data fork of a
> fat-app, it won't confuse the loader or whatever else Apple might have
> in store for the data fork in the future, right? <hope, hope, cross
> fingers>
The resource which tells the system where to look for the code fragment(s)
provides for this. But it's probably cleaner not to put variable-length
data in there, or even mutable but fixed length data.
> Is there a convention for writing fat-code? That is, can I just build
> a CODE resource for 68K, then do what I normally do to build a fat-app
> but wave the magic wand over the CODE resource instead, and append the
> PPC code onto that resource file and wind up with a fat-loadable code
> module? If I can, is there a single calling convention for both
> loadable code modules (this refers back to my first question)?
Above references.
--
John Baxter Port Ludlow, WA, USA [West shore, Puget Sound]
No hablo Intel.
jwbaxter@pt.olympus.net
+++++++++++++++++++++++++++
>From winter@ai.rl.af.mil (Jim Wintermyre)
Date: Tue, 19 Jul 1994 19:23:13 GMT
Organization: Rome Laboratory
In article <CsyvBJ.Ku3@newsflash.concordia.ca>
ikb_macd@ECE.Concordia.CA (Keith MacDonald) writes:
> to a program I'm working on. These files would (I assume) contain code
> resources. I've not been able to find any examples or clear description
> of what I need to do to achieve this. I'm using Pascal, but I imagine
Check out MacTech vol. 9 no. 9 (Sept 93), "External Code Modules in
Pascal." Also check out the tech note "Stand-Alone Code ad nauseum."
> Also related to code resources -
> would it be possible to have a C PPC native code resource used by
> a non-native (written in Think Pascal) application?
I believe so, but I'm not sure of the details. Check out the Mixed
Mode and Code Fragment Manager chapters in New Inside Mac: Power PC
System Software.
Jim Wintermyre (Opinions expressed are my own, of course)
winter@ai.rl.af.mil
wintermyrej@lonex.rl.af.mil
---------------------------
>From amundson@phenom.physics.wisc.edu (James F. Amundson)
Subject: Can I do this with the Thread Manager?
Date: Sat, 16 Jul 1994 21:05:16 -0600
Organization: Division of Information Technology
Can someone tell me if what I have in mind is possible? I want to use the
Thread Manager to give me basic preemptive multitasking without much
thought.
My situation is this: I'm not writing a Mac application. I'm using Think C
7.0 to run scientific calculations. My programs are entirely ANSI C with
no toolbox calls other than those from the Think C ANSI libraries. I'd
like to be able to run the programs I write without taking over my mac
while they run. In the past, I've hacked them to call WaitNextEvent
occasionally. The problem is that it takes a fair amount of effort on my
part to decide where and how often I need to call WNE. Since the nature of
my work involves constantly changing the programs I'm writing, adjusting
my calls to WNE every time is impractical.
Can I use the Thread Manager without much effort? Are there any examples
of this sort of thing?
Any advice will be appreciated.
Thanks,
Jim Amundson
+++++++++++++++++++++++++++
>From first.ascent@mindlink.bc.ca (Alex Curylo)
Date: 17 Jul 1994 03:17:02 GMT
Organization: MIND LINK! Communications Corp.
In article <amundson-1607942105160001@f180-186.net.wisc.edu>
amundson@phenom.physics.wisc.edu (James F. Amundson) writes:
> Can I use the Thread Manager without much effort? Are there any examples
> of this sort of thing?
Grab develop 17, and a copy of CodeWarrior 3.5. The latest iteration of
PowerPlant includes a nice selection of thread classes. They're being
used in a project I'm working on right now, and the fellow using them
seems to have fairly positive regard for them. And for the rest of
PowerPlant, as soon as they finish it ;)
+++++++++++++++++++++++++++
>From rmah@panix.com (Robert Mah)
Date: Sun, 17 Jul 1994 00:53:05 -0500
Organization: One Step Beyond
amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
) I'm using Think C 7.0 to run scientific calculations. My programs are
) entirely ANSI C with no toolbox calls other than those from the Think
) C ANSI libraries. I'd like to be able to run the programs I write
) without taking over my mac while they run. In the past, I've hacked
) them to call WaitNextEvent occasionally. The problem is that it takes
) ...
) Can I use the Thread Manager without much effort? Are there any examples
) of this sort of thing?
Thread Manager can do pre-emptive threads, _but_ only on 68K Macs. In
addition, pre-emptive threads must obey the same rules as interupt level
code. I.e. no drawing, no moving memory, etc.
There's examples in Develop 17 that goes over using the Thread Mgr, but
since using co-operative threads won't gain you much (you'll still have
to call Yield() occaisionally) you should look at your code and see if
you can use pre-emptive threads.
Cheers,
Rob
_____________________________________________________________________
Robert S. Mah : Macintosh software development : 212.947.6507
One Step Beyond : and network consulting : rmah@panix.com
+++++++++++++++++++++++++++
>From gwatts@fnal.fnal.gov (Gordon Watts)
Date: Mon, 18 Jul 1994 00:09:54 -0600
Organization: Fermi Lab
In article <rmah-1707940053050001@rmah.dialup.access.net>, rmah@panix.com
(Robert Mah) wrote:
> amundson@phenom.physics.wisc.edu (James F. Amundson) wrote:
>
> ) I'm using Think C 7.0 to run scientific calculations. My programs are
> ) entirely ANSI C with no toolbox calls other than those from the Think
> ) C ANSI libraries. I'd like to be able to run the programs I write
> ) without taking over my mac while they run. In the past, I've hacked
> ) them to call WaitNextEvent occasionally. The problem is that it takes
> ) ...
> ) Can I use the Thread Manager without much effort? Are there any examples
> ) of this sort of thing?
>
> Thread Manager can do pre-emptive threads, _but_ only on 68K Macs. In
> addition, pre-emptive threads must obey the same rules as interupt level
> code. I.e. no drawing, no moving memory, etc.
>
> There's examples in Develop 17 that goes over using the Thread Mgr, but
> since using co-operative threads won't gain you much (you'll still have
> to call Yield() occaisionally) you should look at your code and see if
> you can use pre-emptive threads.
>
> Cheers,
> Rob
It depends upon what ANSI C library calls you make. If you make calls to
printf, etc. then the short answer is ... well, no. Calls to things like
sqrt, etc. are ok. Basically, any call that will cause the screen to be
drawn to or memory to be moved (malloc, etc.) will break with the
pre-emptive threads.
There are two things you can do, if you still want to use the threads.
First, you can isolate your calls to printf and the like so they are never
called in a preemptive thread (a thread is preemptive or cooperative when
it is created, and cannot change during its lifetime).
Second, and perhaps simpler, is you can implement your calculation as a
cooperative thread. Sprinkle calls to "Yield()" all over the place, but
don't worry too much about the placement. Just make sure there are enough
of them. Now, in your main event loop you can put something like the
following (this code has not been compiled/debugged!):
while (!gDone) { // gDone will be set by your calc when it is finished...
current_time = TickCount () + 30; // Current time plus 1/2 a second
while (current_time > TickCount ())
Yield (); // Go off and do some real calculations for a 1/2 second
WaitNextEvent (...);
}
Excuse the formatting... You will incure dead time in the Yield call, I'm
not sure how much speed you are trying to get out. The fact that you are
calling WaitNextEvent means that you are willing to give up some time...
This will require little modification to your current application, I
suspect.
One bad thing about using threads if you have to figure out what your
stack usage is before you run your calculation -- threads don't have a
stack that grows as need be. This might be bad if you are doing lattice
calculations and allocate large arrays on the stack (do it globally at
compile time or by malloc while running).
You can use all calls in cooperative threads, printf, malloc, etc. etc.
and they will work on the powerpc.
Cheers,
Gordon (high energy physics).
--
Gordon Watts -- gwatts@fnal.fnal.gov
+++++++++++++++++++++++++++
>From Dave Falkenburg <falken@apple.com>
Date: Wed, 20 Jul 1994 16:43:41 GMT
Organization: Apple Computer, Inc.
In article <gwatts-1807940009540001@slip113.fnal.gov> Gordon Watts,
gwatts@fnal.fnal.gov writes:
>while (!gDone) { // gDone will be set by your calc when it is
finished...
>
> current_time = TickCount () + 30; // Current time plus 1/2 a second
>
> while (current_time > TickCount ())
> Yield (); // Go off and do some real calculations for a 1/2 second
>
> WaitNextEvent (...);
>}
GACK!
Please use a dynamic value for adjusting sleep timings like this: i.e.
replace the "+30" with "+gRunQuantum", a value that is computed
dynamically based on the compute power of the CPU. The code above means
that even if we make the MacOS 100x faster, you might limit the ability
for the user to switch applications down to once every two seconds.
HALF A SECOND IS ALOT OF CPU TIME TO BE EATING without yielding control
to other applications.
-Dave Falkenburg
-Apple Computer, Inc.
---------------------------
>From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
Subject: Dice Rolling - answers
Date: Thu, 21 Jul 1994 08:12:12 -0700
Organization: Ministry of Environment, Lands & Parks
Finally, after much fiddling and examining of code, I finally got my dice
animation working in my game. There is a trick to it.
Because many people helped me, I thought I would post what I found so that
others can be helped too.
First, a little background. I use 3 global GWorlds to hold (a) all six
dice from a PICT resource, (b) the mask and (c) a working area. This set
up is similar to how john calhoun did his games like Glypa II. As
mentioned above, these are all global, so I can access them from
anywhere. I also use a custom window record structure that includes a
GWorld which has the contents of the window in it. This is used for
really fast updates (See Mac Prog. Secrets, ch 6 for more details)
Now that all the GWorlds are set up and the items are in them, I use
CopyMask (speed is not important in this game) to copy the dice from the
diceWorld and the mask from the maskWorld to the workWorld. (with me so
far?) This is a simple call. I use it twice as I have 2 dice I want to
display and "roll". I can then use CopyBits to copy the workWorld to my
window's offscreen GWorld for updating purposes. No problems here.
The trick comes when you want to copy the dice from the GWorld to the
window. When you use GWorlds, you always use GetGWorld and SetGWorld when
copying from 1 GWorld to another. However, if you use this when you want
to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
this in the debugger in THINK C 7.0.3 and I still couldn't get out.
cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
RAM). So what you have to do is use GetPort and SetPort when copying to
the window. This works without a hitch.
I then use CopyMask as I did before to copy the dice to the workWorld and
CopyBits to copy from the workWorld to the window. This is still pretty
fast despite the intermediate steps. I've seen some code by Tony Myles
that I got off of ftp.apple.com called CopyBits vs. CopyMask. He uses
CopyBits with a maskRgn to copy to the window. This is much faster. But
like I said, I don't need speed. Also, you can just plain elimate the
intermate step and CopyMask directly to the window instead of the
workWorld and then the window.
Thanks to many people on the Net for donating code (Ken Long) and help
(Aaron Giles, Ingemar R., et al.) so that I can actually get this to work.
--
========================================================================
Carl B. Constantine B.C. Environment, Lands & Parks
End-User Support Analyst CCONSTAN@epdiv1.env.gov.bc.ca
PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
+++++++++++++++++++++++++++
>From s828963@kub.nl (Peter Berck)
Date: 22 Jul 1994 12:21:53 GMT
Organization: KUB, The Netherlands
In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>, cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
|> Finally, after much fiddling and examining of code, I finally got my dice
|> animation working in my game. There is a trick to it.
|>
|> Because many people helped me, I thought I would post what I found so that
|> others can be helped too.
|>
[snip]
|>
|> The trick comes when you want to copy the dice from the GWorld to the
|> window. When you use GWorlds, you always use GetGWorld and SetGWorld when
|> copying from 1 GWorld to another. However, if you use this when you want
|> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
|> this in the debugger in THINK C 7.0.3 and I still couldn't get out.
|> cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
|> RAM). So what you have to do is use GetPort and SetPort when copying to
|> the window. This works without a hitch.
Uhm? Are you sure? I am writing a program which also has an offscreen
GWorld which is copied to the screen (using CopyBits) when necessary.
I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
QuickDraw mentions somewhere (don't have it on me, so I can't give you
the page number) that you should use SetGWorld/GetGWorld instead of
GetPort and SetPort.
Now I'm slightly confused. I have just started to use GWorld stuff,
and I was pretty sure that Get/SetGWorld was all I needed, so if any
macguru can enlighten me I'd be very grateful...
-Peter
- ----------------------------------------------------------------
P.J.Berck@kub.nl pgp-pubkey on request
(format t "~&~{~<~%~1:;~a~>~^,~}.~%"
'(DoD#-337 The-Ex Sonic-Youth NIN Dante-Alighieri Guinness))
+++++++++++++++++++++++++++
>From cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine)
Date: Fri, 22 Jul 1994 11:30:50 -0700
Organization: Ministry of Environment, Lands & Parks
In article <30odl1$7ro@kubds1.kub.nl>, P.J.Berck@kub.nl wrote:
> In article <cconstan-2107940812120001@eusacbc.env.gov.bc.ca>,
cconstan@epdiv1.env.gov.bc.ca (Carl B. Constantine) writes:
> |> Finally, after much fiddling and examining of code, I finally got my dice
> |> animation working in my game. There is a trick to it.
> |>
> |> Because many people helped me, I thought I would post what I found so that
> |> others can be helped too.
> |>
> [snip]
> |>
> |> The trick comes when you want to copy the dice from the GWorld to the
> |> window. When you use GWorlds, you always use GetGWorld and SetGWorld when
> |> copying from 1 GWorld to another. However, if you use this when you want
> |> to copy to the window, CopyBits makes your Mac CRASH big time!! (I ran
> |> this in the debugger in THINK C 7.0.3 and I still couldn't get out.
> |> cmd-opt-esc didn't do much, I had to restart. I have an LCIII with 12MB
> |> RAM). So what you have to do is use GetPort and SetPort when copying to
> |> the window. This works without a hitch.
>
> Uhm? Are you sure? I am writing a program which also has an offscreen
> GWorld which is copied to the screen (using CopyBits) when necessary.
> I use SetGWorld and GetGWorld all the time. In fact, NIM:Imaging with
> QuickDraw mentions somewhere (don't have it on me, so I can't give you
> the page number) that you should use SetGWorld/GetGWorld instead of
> GetPort and SetPort.
>
> Now I'm slightly confused. I have just started to use GWorld stuff,
> and I was pretty sure that Get/SetGWorld was all I needed, so if any
> macguru can enlighten me I'd be very grateful...
>
It crashed my mac considerably. However, I'm piggybacking a GWorldPtr
onto a custom windowRecord structure. this may be why it's crashing. I'm
not sure, I haven't tested it otherwise (I don't have NIM: Imaging). I'd
have to test.
I have it off hand from a good source (Aaron Giles, writer of JPEGView)
that you SHOULD always used GetGWorld & SetGWorld. I'm not sure why it
was crashing in my system, but it was so I left it with GetPort & SetPort.
Hope this helps.
--
========================================================================
Carl B. Constantine B.C. Environment, Lands & Parks
End-User Support Analyst CCONSTAN@epdiv1.env.gov.bc.ca
PGP Key available if you finger: CCONSTAN@EUSACBC.env.gov.bc.ca
+++++++++++++++++++++++++++
>From kenlong@netcom.com (Ken Long)
Date: Sat, 23 Jul 1994 14:24:16 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Here are some fragments/snippets from Mark Hanrek, on the subjuct, ala
NuCube (some names changed for another program):
- -----------
WindowPtr starsWindow; // Windows and GWorlds are the same thing, so
GWorldPtr gOffscreenGWorld; // use only Get/SetGWorld calls in
// this app.screen" area in the window
Rect gOffscreenRect; // The offscreen rect's upper-left is 0,0
Rect gProjectionRect; // The projection Rect
//*******************************************************************//
// Create window, offscreen GWorld, and one control for starters //
//*******************************************************************//
void SetupWindow (void)
{
Rect tempRect;
//------ Set up our main window, man
starsWindow = GetNewWindow (rWIND, nil, (WindowPtr) -1L);
SetPort (starsWindow);
ShowWindow (starsWindow);
SetRect (&gProjectionRect, kHorizOffset, kVertOffset,
kHorizOffset+kCubeSide, kVertOffset+kCubeSide);
//¥ Set up an offscreen GWorld for preparing the next cube's image.
SetRect (&gOffscreenRect, 0, 0, kCubeSide, kCubeSide);
gOffscreenGWorld = CreateOffscreenGWorld (&gOffscreenRect);
}
void RotateCubeOnce (void)
{
long ticksNow;
GWorldPtr windowGW;
GDHandle windowGD;
PixMapHandle thePixMap;
GetGWorld (&windowGW, &windowGD); // Save whatever we had before
SetGWorld (gOffscreenGWorld, nil);
if (LockPixels (thePixMap = GetGWorldPixMap (gOffscreenGWorld)))
{
EraseRect (&gOffscreenGWorld->portRect);
//======================================================
(action)
//======================================================
//
// Always set the current port to a window's port before
// drawing from
// a GWorld, so that the Window Manager can "clip" the
// image properly
// should there be other windows in front. Comment out
// the next statement
// and notice what happens when you drag another window in front of
// the NuCube window. :)
//
SetGWorld (windowGW, windowGD); // Focus on a real window
CopyBits ((BitMapPtr)*thePixMap,
(BitMapPtr)&starsWindow->portBits,
&gOffscreenRect,
&gProjectionRect, srcCopy, nil);
UnlockPixels (thePixMap);
}
SetGWorld (windowGW, windowGD); // Okay if this is redundant
}
//*******************************************************************//
// Use the following function for the rest of your programming
// days.
// Do not alter it in any way. It is a complete functional unit
// doing all REQUIRED things.
//*******************************************************************//
GWorldPtr CreateOffscreenGWorld (Rect *theRect)
{
CGrafPtr currentPort;
GDHandle currentGDevice;
GWorldPtr offScreen;
QDErr result;
GetGWorld (¤tPort, ¤tGDevice);
//-- If there is not enough application memory, try MultiFinder
//-- temporary memory.
if ((result = NewGWorld (&offScreen, 0, theRect, nil, nil, 0L))
!= noErr)
if ((result = NewGWorld (&offScreen, 0, theRect, nil,
nil, useTempMem)) != noErr)
return (nil);
SetGWorld (offScreen, nil);
//-- Initialize the clipping "hole" to be the same as the
//-- drawing area.
ClipRect (&offScreen->portRect);
//-- The GWorld has random stuff in it, so we'll erase it to
//-- white.
if (LockPixels (GetGWorldPixMap (offScreen)))
{
ForeColor (blackColor);
BackColor (whiteColor);
EraseRect (&offScreen->portRect);
UnlockPixels (GetGWorldPixMap (offScreen));
}
SetGWorld (currentPort, currentGDevice);
return offScreen;
}
//*******************************************************************//
// Shut down with charm, grace and decorum.
//*******************************************************************//
void MoveAlongHome (void)
{
DisposeWindow (starsWindow); // Not "CloseWindow"
DisposeGWorld (gOffscreenGWorld);
}
- --------------
That's all, folks.
-Ken-
---------------------------
>From rkwee@ee.pdx.edu (Roland Kwee)
Subject: Easy file access functions [source]
Date: 18 Jul 1994 20:35:28 -0700
Organization: (none)
Some days ago I promised to upload some source code that makes handling
Mac file functions as easy as the standard ANSI C library functions.
Hopefully I didn't leave out code that is essential to understand and
use my little system.
Here is my Macintosh ThinkC source code for accessing files pretty much like
with the ANSI C library functions. Hopefully the code is sufficiently
commented to be understandible. Note that there is a test function that
demonstrates how to use the other functions.
Please let me know if this is useful, understandable, and if you see
problems or improvements.
--Roland Kwee email: RolandKwee@ACM.org
/*----------------------------------------------------------------------------------
* globals.h Roland Kwee May 25, 1994
* This file contains the declarations for the application-specific global data.
*
* A good strategy may be to declare a number of global variables in a single
* structure. With the menu options, the user can change one or more of these
* global settings. These settings are global to allow easy access by the
* functions that actually perform tasks. By keeping them in a single
* structure, they are easy to keep track of.
*----------------------------------------------------------------------------------
*/
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
enum Creators{CREATOR='TrRK'};
enum FileTypes{UNKNOWN, PostScript, Binary,
TextDos, TextUnix, TextMac,
Hathaway, Rochester, RochesterHeader, BEN5000,
PPSM, Support, Spreadsheet};
/* This structure communicates user input to the process. */
struct Option_s{
int Quit;
int SeparateDigCh, OutputType, LPFcorrection, DiagnosticWindow, ProgressDialog, Fast;
int debug, test_partly; /* default: 0 (no debug output). */
void *OpenFileList, *PrintFileList;
float TimeZoneHourOffset;
char DefaultLocation[5];
};
extern struct Option_s Option;
#endif /* __GLOBALS_H__ */
/* MacFile.h Roland Kwee June 1, 1994
* Functions to make handling files on the Mac almost as easy as in Unix.
* This will make it possible to port programs between Unix and the Mac.
*/
#ifndef _MACUTIL_H__
#define _MACUTIL_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
//==============
// Project Info:
//==============
// compiler: Symantec C++ for Macintosh, 1994, ThinkC (version 7 ?)
// libraries: MacTraps, SANE, ANSI
// Executable:
// file name: Translate
// File Type: APPL, Creator: TrRK
// Compiler settings:
// int: 2 bytes
// float: 4 bytes
// double: 8 bytes
// don't use the "native" floating point format
#if __option(native_fp)
#error Don't use the "native" floating point format (Edit/Options/Compiler settings).
#endif
// printf can only handle float and doubles if double is not set to 8 bytes:
#if __option(double_8)
#error Don't set doubles to 8 bytes (Edit/Options/Compiler settings).
#endif
// REASONS FOR FLOATING POINT SETTINGS:
// The input file has IEEE double numbers, but the input routine is able to convert these
// to Mac format using the Mac type `short double' which is equal to IEEE double.
// The library function printf is compiled with the standard settings, so the formats for
// floating point will work incorrectly if the program is compiled with the `8-byte doubles' option.
// Better not to recompile the library, so set all floating point options to Mac standard.
/* ===============definitions for byte order ===================== */
enum {BigEndian /* Motorola, VAX */, LittleEndian /* Intel */};
//extern int computerbyteorder;
#define computerbyteorder BigEndian
/*=========================== TIME ZONE ============================*/
/* This should be a menu option. For now it is constant.
* Valid values are -12.0 .. 12.0. Positive is East of Greenwich.
* Simple fractions like 9.5 (Adelaide, Australia) should work.
*/
#define TZ -7
/* This global can be used with sprintf to prepare a string to pass to Log(). */
extern char buf[1000];
void Log(char *msg);
void SystemError(char *msg, char *source, int code);
void Warn(char *msg);
char *PtoCstrPtr(void *Pstring);
void LtoCstr(OSType l, char *s);
char *FSStoCstrPtr(FSSpec *file);
char *GetBaseName(FSSpec *file);
char *GetFullPathName(FSSpec *file);
void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath);
int FSSpecRoutinesAvail(void);
FSSpec *select_input_file(const int numTypes, SFTypeList myTypes);
FSSpec *select_output_file(const char *prompt, const char *defname);
void FinderInfo(FSSpec *fs);
void PathInfo(FSSpec *fs);
char *GetVolumeName(FSSpec *fs);
void VolumeInfo(FSSpec *fs);
void TestPathUtils(void);
#if 0 /* See Mac include file <files.h> */
struct FSSpec {
short vRefNum;
long parID;
Str63 name;
};
typedef struct FSSpec FSSpec;
typedef FSSpec *FSSpecPtr, **FSSpecHandle;
typedef FSSpecPtr FSSpecArrayPtr; /* pointer to array of FSSpecs */
#endif
typedef struct{
int in_use; /* To maintain the file table. */
FSSpec fss; /* Specification of the (closed) file selected with a dialog. */
short refnum; /* Reference number, or access path of the open file. */
int byteorder;
}MacFILE;
/* This structure is currently only used to hold the year of a file.
* It doesn't really matter whether last access or last modify.
*/
struct MacStat{
long st_size; /* total size of file, in bytes */
int year;
#if 0
time_t st_atime; /* file last access time */
time_t st_mtime; /* file last modify time */
time_t st_ctime; /* file last status change time */
#endif
};
#define File MacFILE
#define FileRead macfread
#define FWRITE macfwrite
#define FSEEK macfseek
#define FSTAT macfstat
#define STAT_T struct MacStat
MacFILE *macftype(FSSpec *selection, long creator, long type);
MacFILE *macfopen(FSSpec *selection, char *mode);
int macfclose(MacFILE *fp);
int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp);
int macfseek(MacFILE *fp, long offset, int whence);
long macftell(MacFILE *fp);
int macfstat(MacFILE *fp, struct MacStat *buf);
void copy_file(MacFILE *fp_in, MacFILE *fp_out);
int TestFileType(MacFILE *fp);
void TestFileUtils(void);
void BetterMoveWindow(WindowPtr wp, float right, float down);
void SwapN(void *buf, int n);
int NeedSwap(MacFILE *fp, void *buf, int n);
char GetInputByte(File *fp); // Reads and returns one byte.
int GetInputInt(File *fp); // Reads, converts and returns one integer.
long GetInputLong(File *fp);
unsigned long GetInputULong(File *fp);
float GetInputFloat(File *fp);
double GetInputDouble(File *fp); /* reads IEEE 8-byte double, returns Mac double. */
/* GetInputString - Reads a string and returns a null-terminated C-string.
Reading stops when a '\0' char, or `size' characters have
been read. A '\0' is added.
If you are certain that the string to read is terminated with a '\0',
then `size' can be the size of the buffer. Otherwise, the buffer needs to be
one character bigger, to hold the added '\0'.
*/
char *GetInputString(char *buf, int size, File *fp);
/* GetInputNString - Reads n characters and returns a string in str.
str needs to have room for an additional '\0'. */
char *GetInputNString(char *str, int n, File *fp);
/* SwapN - swaps n bytes of buf in place */
void SwapN(void *buf, int n);
// Writes a C string to the output file.
int WriteTxt(File *fp, char *str);
// Writes bytes to a binary output file.
int WriteBin(File *fp, void *buf, int size);
// Specialized functions to write data, argument may be a constant
void WriteULong(File *fp, unsigned long x);
void WriteLong(File *fp, long x);
void WriteShort(File *fp, signed short x);
#endif /* _MACUTIL_H__ */
/* MacFile.c Roland Kwee June 1, 1994
* Functions to make handling files on the Mac almost as easy as in Unix.
* This will make it possible to port programs between Unix and the Mac.
*/
#include "MacFile.h"
#include "globals.h"
#include <GestaltEqu.h>
#include <console.h> /* cshow() */
/* This global can be used with sprintf to prepare a string to pass to Log(). */
char buf[1000];
/*----------------------------------------------------------------------------------
* Log() - Diagnostic output. Adds a newline at the end.
*----------------------------------------------------------------------------------*/
void Log(char *msg){
if(Option.debug)
puts(msg);
return;
}
/*----------------------------------------------------------------------------------
* SystemError() - Error output. Should be a alert box.
*----------------------------------------------------------------------------------*/
void SystemError(char *msg, char *source, int code){
/* Force visible output. */
if(!Option.debug){
Option.debug=1;
cshow(stdout);
}
sprintf(buf, "Error: %s%s%s code: %d", msg, source?" in function: ":"",
source?source:"", code);
Log(buf);
return;
}
/*----------------------------------------------------------------------------------
* Warn() - Warning output.
*
* Should be a modal dialog box IF the diagnostic window is closed.
* Or, there should be an option to suppress the modal dialog box to
* allow unattended transfer of large batches of files.
*
*----------------------------------------------------------------------------------*/
void Warn(char *msg){
Log(msg);
return;
}
/*----------------------------------------------------------------------------------
* PtoCstrPtr() - Converts a Pascal string to a pointer to a C String.
* The string the pointer points to is reused for each new call.
*----------------------------------------------------------------------------------*/
char *PtoCstrPtr(void *Pstring){
static char Cstring[257];
char *str;
int i, max;
str=Pstring;
max=str[0];
memcpy(Cstring, str+1, max);
Cstring[max]='\0';
return Cstring;
}
/*----------------------------------------------------------------------------------
* LtoCstr() - Converts an OSType (long) to a C-string (char[5]).
*----------------------------------------------------------------------------------*/
void LtoCstr(OSType l, char *s){
//sprintf(buf, "LtoCstr: 0x%08X", l); Log(buf);
memcpy(s, (char*)&l, 4);
s[4]='\0';
return;
}
/*----------------------------------------------------------------------------------
* FSStoCstrPtr() - Converts a FSS file specification to a C string.
* The string the pointer points to is reused for each new call.
* See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
*----------------------------------------------------------------------------------*/
char *FSStoCstrPtr(FSSpec *file){
static char fullPath[300];
CInfoPBRec myPB;
Str255 dirName;
OSErr myErr;
strcpy(fullPath, PtoCstrPtr(file->name));/* Start with base file name. */
myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
myPB.dirInfo.ioVRefNum=file->vRefNum; /* Volume ID */
myPB.dirInfo.ioDrParID=file->parID; /* Initialize parent dir. */
myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
myPB.dirInfo.ioCompletion=NULL;
for( myPB.dirInfo.ioDrDirID=file->parID;
myPB.dirInfo.ioDrDirID!=fsRtDirID;
myPB.dirInfo.ioDrDirID=myPB.dirInfo.ioDrParID){
myErr=PBGetCatInfo(&myPB, FALSE);
if(myPB.dirInfo.ioResult==noErr){
strcat(fullPath, ":");
strcat(fullPath, PtoCstrPtr(dirName));
}else
break;
}
return fullPath;
}
/*----------------------------------------------------------------------------------
* GetBaseName() - Converts a FSS file specification to a C string containing
* the base file name, i.e., without the path.
* The string the pointer points to is reused for each new call.
*----------------------------------------------------------------------------------*/
char *GetBaseName(FSSpec *file){
static char fullPath[100]; /* Semi-permanent, reused. */
strcpy(fullPath, PtoCstrPtr(file->name)); /* Add file name. */
return fullPath; /* Return pointer. */
}
/*----------------------------------------------------------------------------------
* GetFullPathName() - Converts a FSS file specification to a C string containing
* the full path and the file name.
* The string the pointer points to is reused for each new call.
* See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
*----------------------------------------------------------------------------------*/
char *GetFullPathName(FSSpec *file){
static char fullPath[1000]; /* Semi-permanent, reused. */
strcpy(fullPath, GetVolumeName(file)); /* Start with disk name. */
strcat(fullPath, ":"); /* Path always ends with colon. */
GetFullPath(file->vRefNum, file->parID, fullPath); /* Find full path. */
strcat(fullPath, PtoCstrPtr(file->name)); /* Add file name. */
return fullPath; /* Return pointer. */
}
/*----------------------------------------------------------------------------------
* GetFullPath() - Returns full path name (without file name) in fullPath. Recursive.
*
* See: New Inside Mac, "Files", p. 2-45: Constructing Full Pathnames, Listing 2-5.
* Because strcat() cannot handle overlapping strings, recursion is easier than
* an iteration. The parts of the path are pasted together AFTER all parts are found.
*----------------------------------------------------------------------------------
*/
void GetFullPath(int VolumeSpec, long ParentDirID, char *fullPath){
Str255 dirName;
CInfoPBRec myPB;
OSErr myErr;
myPB.dirInfo.ioVRefNum=VolumeSpec;
myPB.dirInfo.ioDrDirID=ParentDirID;
myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
myPB.dirInfo.ioCompletion=NULL;
myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
myErr=PBGetCatInfo(&myPB, FALSE); /* receive parent dir in dirName */
if(myErr==noErr){
if(myPB.dirInfo.ioDrParID!=fsRtDirID) /* This is the root dir ID. */
GetFullPath(VolumeSpec, myPB.dirInfo.ioDrParID, fullPath); /* RECURSION */
strcat(fullPath, PtoCstrPtr(dirName)); /* paste parent to ancestors */
strcat(fullPath, ":"); /* Path always ends with colon. */
}
return;
}
/*----------------------------------------------------------------------------------
* FSSpecRoutinesAvail() - Returns true if the FSS functions are available.
*----------------------------------------------------------------------------------
*/
int FSSpecRoutinesAvail(void){
OSErr myErr = !noErr;
long myFeature;
int avail=0;
if(1/*gHasGestalt()*/){
myErr=Gestalt(gestaltFSAttr, &myFeature);
if(myErr==noErr && (myFeature & gestaltHasFSSpecCalls))
avail=1;
else
Log("Gestalt error");
}else
Log("Gestalt is not available");
if(avail)
Log("FSS Routines Available");
return avail;
}
/*----------------------------------------------------------------------------------
* select_input_file() - Allows the user to select an input file with a standard dialog box.
* If numTypes == -1, all file types are displayed.
* Returns: pointer to FSS record, or NULL on error or cancel.
* See: New Inside Mac, "Files", p. 1-19: Opening a File, Listing 1-6.
*----------------------------------------------------------------------------------*/
FSSpec *select_input_file(const int numTypes, SFTypeList myTypes){
static StandardFileReply myReply;
OSErr myErr=noErr;
StandardGetFile(NULL, numTypes, myTypes, &myReply);
if(myReply.sfGood){
char type[5];
LtoCstr(myReply.sfType, type);
sprintf(buf, "select_input_file: Type: %s", type); Log(buf);
return &myReply.sfFile;
}else
return NULL;
}
/*----------------------------------------------------------------------------------
* select_output_file() - Allows the user to select an output file with a standard dialog box.
* Returns: pointer to FSS record, or NULL on error or cancel.
*----------------------------------------------------------------------------------*/
FSSpec *select_output_file(const char *prompt, const char *defname){
Str255 Pprompt, Pdefname;
static StandardFileReply myReply;
OSErr myErr=noErr;
strcpy((char *)Pprompt, prompt); CtoPstr((char *)Pprompt);
strcpy((char *)Pdefname, defname); CtoPstr((char *)Pdefname);
/* The cursor is set to an I-beam to edit the file name in the
* dialog box. Reset it to the default arrow. */
StandardPutFile(Pprompt, Pdefname, &myReply);
InitCursor();
if(myReply.sfGood){
return &myReply.sfFile;
}else
return NULL;
}
/*----------------------------------------------------------------------------------
* FinderInfo() - Test output of Finder Info of a file: creator, type...
*----------------------------------------------------------------------------------*/
void FinderInfo(FSSpec *fs){
OSErr myErr;
FInfo fndrInfo;
char creator[5], type[5];
myErr=FSpGetFInfo(fs, &fndrInfo);
LtoCstr(fndrInfo.fdType, type);
LtoCstr(fndrInfo.fdCreator, creator);
Log("-------------------------");
strcpy(buf, "Getting Finder Info: ");
switch(myErr){
case noErr: strcat(buf, "No error"); break;
case nsvErr: strcat(buf, "No such volume"); break;
case ioErr: strcat(buf, "I/O error"); break;
case bdNamErr: strcat(buf, "Bad filename"); break;
case fnfErr: strcat(buf, "File not found"); break;
case paramErr: strcat(buf, "No default volume"); break;
case dirNFErr: strcat(buf, "Directory not found or incomplete pathname"); break;
case afpAccessDenied: strcat(buf, "User does not have the correct access"); break;
case afpObjectTypeErr: strcat(buf, "Directory not found or incomplete pathname"); break;
default : strcat(buf, "Unknown error"); break;
}
Log(buf);
if(myErr==noErr){
sprintf(buf, "Type: '%s' Creator: '%s', Flags: 0x%04X, Location: X=%d Y=%d, Directory: %d",
type, creator,
fndrInfo.fdFlags, fndrInfo.fdLocation.h, fndrInfo.fdLocation.v,
fndrInfo.fdFldr); Log(buf);
}
return;
}
/*----------------------------------------------------------------------------------
* PathInfo() - Test output with info on the PathID.
*----------------------------------------------------------------------------------*/
void PathInfo(FSSpec *fs){
CInfoPBRec myPB;
Str255 dirName;
OSErr myErr;
myPB.dirInfo.ioNamePtr=dirName; /* Output buffer for PBGetCatInfo(). */
myPB.dirInfo.ioVRefNum=fs->vRefNum; /* Volume ID */
myPB.dirInfo.ioDrDirID=fs->parID;
myPB.dirInfo.ioFDirIndex= -1; /* <0: Use ioDrDirID as input. */
Log("-------------------------");
myErr=PBGetCatInfo(&myPB, FALSE);
sprintf(buf, "Getting Path Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
sprintf(buf, "ID of this dir: %ld, Parent dir: \"%s\"",
myPB.dirInfo.ioDrDirID, PtoCstr(dirName)); Log(buf);
sprintf(buf, "ID of parent dir: %ld, Files in dir: %d",
myPB.dirInfo.ioDrParID, myPB.dirInfo.ioDrNmFls); Log(buf);
return;
}
/*----------------------------------------------------------------------------------
* GetVolumeName() - Returns pointer to the volume name specified in fs.
*----------------------------------------------------------------------------------*/
char *GetVolumeName(FSSpec *fs){
static char name[35]; /* Volume names are up to 27 chars. */
HParamBlockRec myHPB;
OSErr myErr;
myHPB.volumeParam.ioNamePtr=(StringPtr)name;
myHPB.volumeParam.ioVRefNum=fs->vRefNum;
myHPB.volumeParam.ioVolIndex=0;
myErr=PBHGetVInfo(&myHPB, FALSE);
PtoCstr((StringPtr)name);
return name;
}
/*----------------------------------------------------------------------------------
* VolumeInfo() - Test output.
*----------------------------------------------------------------------------------*/
void VolumeInfo(FSSpec *fs){
HParamBlockRec myHPB;
OSErr myErr;
char name[35]; /* Volume names are up to 27 chars. */
long bytes, MB=1024L*1024L;
myHPB.volumeParam.ioNamePtr=(StringPtr)name;
myHPB.volumeParam.ioVRefNum=fs->vRefNum;
myHPB.volumeParam.ioVolIndex=0;
myErr=PBHGetVInfo(&myHPB, FALSE);
Log("-------------------------");
sprintf(buf, "Getting Volume Info: %s", myErr==noErr?"OK":"Error"); Log(buf);
sprintf(buf, "Drive Number: %d, Volume Specification Number: %d",
myHPB.volumeParam.ioVDrvInfo, myHPB.volumeParam.ioVRefNum); Log(buf);
sprintf(buf, "Allocation Block Size: %ld bytes", myHPB.volumeParam.ioVAlBlkSiz); Log(buf);
sprintf(buf, "Clump Size: %ld bytes", myHPB.volumeParam.ioVClpSiz); Log(buf);
sprintf(buf, "Free: %d Allocation Blocks", myHPB.volumeParam.ioVFrBlk); Log(buf);
bytes=myHPB.volumeParam.ioVFrBlk * myHPB.volumeParam.ioVAlBlkSiz;
sprintf(buf, "Name: %s, Free: %ld bytes = %g MB",
PtoCstrPtr(myHPB.volumeParam.ioNamePtr), bytes, (float)bytes/MB); Log(buf);
return;
}
/*----------------------------------------------------------------------------------
* TestPathUtils()
*----------------------------------------------------------------------------------*/
void TestPathUtils(void){
FSSpecRoutinesAvail();
/* Test of PtoCstrPtr(). */
{
char *str;
Str255 Pstr="\pHello";
str=PtoCstrPtr(Pstr);
Log(str);
}
/* Test of select_input_file(). */
{
SFTypeList myTypes;
FSSpec *fs;
//myTypes[0]='TEXT';
fs=select_input_file(-1, myTypes);
if(fs==NULL){
Log("Error select_input_file() or user cancelled");
return;
}
FinderInfo(fs);
VolumeInfo(fs);
PathInfo(fs);
if(fs){
Log("-------------------------");
Log("Getting full name");
{
char *fullname=FSStoCstrPtr(fs);
sprintf(buf, "FSStoCstrPtr: %s", fullname);Log(buf);
fullname=GetFullPathName(fs);
sprintf(buf, "GetFullPathName: %s", fullname);Log(buf);
}
Log("-------------------------");
}
}
return;
}
/*----------------------------------------------------------------------------------
* macftype() - Changes the file type and creator if specified.
* Example: macftype(fss, 0L, 'TEXT');
*----------------------------------------------------------------------------------*/
MacFILE *macftype(FSSpec *selection, long creator, long type){
short vRefNum=selection->vRefNum;
long dirID =selection->parID;
Str255 fileName;
FInfo fndrInfo;
/* FSSpec.name is 63 byte string */
memcpy(fileName, selection->name, sizeof(selection->name));
HGetFInfo(vRefNum, dirID, fileName, &fndrInfo);
if(creator) fndrInfo.fdCreator=creator;
if(type) fndrInfo.fdType =type;
HSetFInfo(vRefNum, dirID, fileName, &fndrInfo);
return;
}
/*----------------------------------------------------------------------------------
* macfopen() - Returns a pointer to an entry in the file table, or NULL on error.
*----------------------------------------------------------------------------------*/
MacFILE *macfopen(FSSpec *selection, char *mode){
/* This is the file table. */
static MacFILE mac_file_table[FOPEN_MAX]; /* Like ANSI C */
int i;
OSErr myErr;
SignedByte permissions;
if(selection==NULL) return;
/* Find a free slot. */
for(i=0; i<FOPEN_MAX && mac_file_table[i].in_use; i++);
if(i==FOPEN_MAX)
return NULL;
/* Translate mode to permissions. */
if(strchr(mode, 'w')){
HParamBlockRec myHPB;
OSErr myErr;
long bytes, MB=1024L*1024L;
myHPB.volumeParam.ioNamePtr=NULL;
myHPB.volumeParam.ioVRefNum=selection->vRefNum;
myHPB.volumeParam.ioVolIndex=0;
myErr=PBHGetVInfo(&myHPB, FALSE);
/* Check if the volume is locked. FSpOpenDF() will still open the
* file for write access, but writing will cause an error.
* See New Inside Mac, "Files", p. 2-8.
* It recommends calling PGHGetVInfo(), which is described at p. 2-144.
* HOWEVER, I can't find the description for the
* volume attributes ioVAtrb ???
*/
//if(myHPB.volumeParam.ioVAtrb & ????????)
// return NULL;
permissions=fsRdWrPerm;
}else
permissions=fsRdPerm;
/* Open it. If file-to-write not found, create it and try again. */
myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
if(myErr==fnfErr && permissions==fsRdWrPerm)
if(noErr==FSpCreate(selection, CREATOR, 'TEXT', smSystemScript))
myErr=FSpOpenDF(selection, permissions, &mac_file_table[i].refnum);
if(myErr!=noErr)
return NULL;
mac_file_table[i].in_use=1;
mac_file_table[i].byteorder=BigEndian; /* Assume it is a Mac type file. */
memcpy(&mac_file_table[i].fss, selection, sizeof(FSSpec));
return &mac_file_table[i];
}
/*----------------------------------------------------------------------------------
* macfclose() - Closes the file and flushes the volume, or returns non-zero on error.
*----------------------------------------------------------------------------------*/
int macfclose(MacFILE *fp){
OSErr myErr;
if(fp==NULL) return;
myErr=FSClose(fp->refnum);
if(myErr==noErr){
FlushVol(NULL, fp->fss.vRefNum);
return 0;
}else
return EOF;
}
/*----------------------------------------------------------------------------------
* macfread() - Like fread().
*----------------------------------------------------------------------------------*/
int macfread(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
OSErr myErr=noErr;
long count=recsize;
int rec;
char *Buffer=buf;
if(fp==NULL) return;
/* Transfer data in the chunks as specified. */
for(rec=0; rec<recnum && myErr==noErr; rec++){
myErr=FSRead(fp->refnum, &count, Buffer);
Buffer += count;
}
/* Count only records that transferred successfully. */
if(myErr!=noErr)
rec--;
/* Return how many records transferred successfully. */
return rec;
}
/*----------------------------------------------------------------------------------
* macfwrite() - Like fwrite().
*----------------------------------------------------------------------------------*/
int macfwrite(void *buf, size_t recsize, size_t recnum, MacFILE *fp){
OSErr myErr=noErr;
long count=recsize;
int rec;
char *Buffer=buf;
if(fp==NULL) return;
/* Transfer data in the chunks as specified. */
for(rec=0; rec<recnum && myErr==noErr; rec++){
myErr=FSWrite(fp->refnum, &count, Buffer);
Buffer += count;
}
/* Count only records that transferred successfully. */
if(myErr!=noErr)
rec--;
/* Return how many records transferred successfully. */
return rec;
}
/*----------------------------------------------------------------------------------
* TestFileType() - Determines what kind the open file is.
*----------------------------------------------------------------------------------*/
int TestFileType(MacFILE *fp){
char buf[100];
int i, ctrl=0, bin=0, ret=0, nl=0, esc=0, Rochester=0, Hathaway=0, ps=0;
if(fp==NULL) return;
if(1==macfread(buf, sizeof(buf), 1, fp)){
/* Test for headers. */
if(!strncmp(buf, "%!", 2)) ps++;
if(!strncmp(buf, "DSM version ", 12)) Hathaway++;
/* Does the Rochester file have a header? */
/* Test the bytes. */
for(i=0; i<sizeof(buf); i++){
switch(buf[i]){
case '\r': ret++; break;
case '\n': nl++; break;
case 0x1B: esc++; break;
case '\t': case '\f': case '\b': case '\v': break;
default:
if(buf[i]<0x1f) ctrl++;
if(buf[i]>0x7f) bin++;
break;
}
}
}
sprintf(buf, "ctrl=%d, bin=%d, ret=%d, nl=%d, esc=%d",
ctrl, bin, ret, nl, esc); Log(buf);
if(Rochester) Log("Rochester Transient Fault Recorder file");
if(Hathaway) Log("Hathaway Digital Signal Monitor file");
if(ps) Log("PostScript file");
if(bin)
Log("Binary file");
else{
if(!ret && nl) Log("Unix text file");
if( ret && !nl) Log("Macintosh text file");
if( ret && nl) Log("MS-DOS text file");
}
return 0;
}
/*----------------------------------------------------------------------------------
* macfseek() - Like fseek().
*----------------------------------------------------------------------------------*/
int macfseek(MacFILE *fp, long offset, int whence){
OSErr myErr;
short posMode;
if(!fp) return -1;
switch(whence){
case SEEK_SET: posMode=fsFromStart; break;
case SEEK_CUR: posMode=fsFromMark; break;
case SEEK_END: posMode=fsFromLEOF; break;
default: return -1; break;
}
myErr=SetFPos(fp->refnum, posMode, offset);
return myErr==noErr?0:-1;
}
/*----------------------------------------------------------------------------------
* macftell() - Like ftell().
*----------------------------------------------------------------------------------*/
long macftell(MacFILE *fp){
OSErr myErr;
long offset;
if(!fp) return -1;
myErr=GetFPos(fp->refnum, &offset);
if(myErr!=noErr) errno=1; /* Required by ANSI C standard. */
return myErr==noErr?offset:-1L;
}
/*----------------------------------------------------------------------------------
* macfstat() - Get file status. Returns zero on success, or -1 on error.
* Not all unix features are implemented yet.
*----------------------------------------------------------------------------------*/
int macfstat(MacFILE *fp, struct MacStat *buf){
static char name[35]; /* Volume names are up to 27 chars. */
HParamBlockRec myHPB; /* New Ins.Mac, `Files', p. 2-269 */
OSErr myErr;
DateTimeRec date;
if(!buf) return -1;
myHPB.volumeParam.ioCompletion=0;
myHPB.volumeParam.ioNamePtr=(StringPtr)fp->fss.name;
myHPB.volumeParam.ioVRefNum=fp->fss.vRefNum;
myHPB.fileParam.ioFDirIndex=0;
myHPB.fileParam.ioDirID=fp->fss.parID;
myErr=PBHGetFInfo(&myHPB, FALSE); /* New Ins.Mac, `Files', p. 2-194 */
Secs2Date(myHPB.fileParam.ioFlMdDat, &date);
buf->year=date.year;
return myErr==noErr?0:-1;
}
/*----------------------------------------------------------------------------------
* copy_file() - For testing.
*----------------------------------------------------------------------------------*/
void copy_file(MacFILE *fp_in, MacFILE *fp_out){
#define recsiz 100
char rec[recsiz];
int irec, nrec, lrec;
long fsiz;
if(!fp_in || !fp_out) return;
/* File size. */
macfseek(fp_in, 0L, SEEK_END);
fsiz=macftell(fp_in);
nrec=fsiz/recsiz;
lrec=fsiz-(nrec*recsiz); /* Size of last, partial, record. */
macfseek(fp_in, 0L, SEEK_SET);
macfseek(fp_out, 0L, SEEK_SET);
sprintf(buf, "File size: %ld bytes = %d chunks of %d bytes plus one of %d bytes",
fsiz, nrec, recsiz, lrec); Log(buf);
/* Transfer full records. */
for(irec=0; irec<nrec; irec++){
if(1!=macfread (rec, recsiz, 1, fp_in)) break;
if(1!=macfwrite(rec, recsiz, 1, fp_out)) break;
}
/* Transfer the last, partial record. */
if(lrec && 1==macfread(rec, lrec, 1, fp_in))
macfwrite(rec, lrec, 1, fp_out);
Log("Copy Done.");
return;
}
/*----------------------------------------------------------------------------------
* TestFileUtils()
*----------------------------------------------------------------------------------*/
void TestFileUtils(void){
MacFILE *fp_in, *fp_out;
FSSpec *fs_in, *fs_out;
SFTypeList myTypes;
StandardFileReply myReply;
Log("Testing the file utility functions");
fs_in=select_input_file(-1, myTypes); /* Input file */
fp_in=macfopen(fs_in, "r");
TestFileType(fp_in);
StandardPutFile("\pFormat: see diagnostic window", "\pdummy", &myReply);
fs_out=myReply.sfGood?&myReply.sfFile:NULL;
fp_out=macfopen(fs_out, "w");
copy_file(fp_in, fp_out);
macfclose(fp_in);
macfclose(fp_out);
return;
}
/*----------------------------------------------------------------------------------
* BetterMoveWindow() - Moves the window partially down and to the right with
* amounts between 0 and 1, where the entire screen size is one.
* The window will not get too close to the border.
*----------------------------------------------------------------------------------*/
void BetterMoveWindow(WindowPtr wp, float right, float down){
Rect r;
short h, w, x, y;
/* Move the box to the center of the screen, horizontally, and
* one-third down, but not too close to the border.
* This is difficult to do with RezEdit.
*/
r=wp->portRect;
h=r.bottom-r.top; /* height */
w=r.right-r.left; /* width */
x=(screenBits.bounds.right-w) * right;
if(x<10) x=10;
y=(screenBits.bounds.bottom-30-h) * down +30; /* Menubar is 30 pixels high. */
if(y<30) y=30;
MoveWindow(wp, x, y, TRUE);
}
/*----------------------------------------------------------------------------------
* SwapN() - swaps n bytes of buf in place, also convert IEEE 8-byte double to
* Macintosh double (12-byte)
*----------------------------------------------------------------------------------*/
void SwapN(void *buf, int n){
char c, *b, *e;
for(b=buf, e=b+n-1; b<e; b++, e--){
c = *b;
*b = *e;
*e = c;
}
return;
}
/*----------------------------------------------------------------------------------
* NeedSwap() - swaps n bytes of buf in place, also convert IEEE 8-byte double to
* Macintosh double (12-byte), BUT ONLY IF NEEDED, i.e., if the byte
* order of the CPU running this program is different from the file type.
* Returns: True if swap was needed.
*----------------------------------------------------------------------------------*/
int NeedSwap(MacFILE *fp, void *buf, int n){
if(computerbyteorder != fp->byteorder){
SwapN(buf, n);
return 1;
}else
return 0;
}
/*==================== INPUT FUNCTIONS =================*/
char GetInputByte(File *fp){
char buf;
long size=sizeof(buf);
FileRead(&buf, size, 1, fp);
return buf;
}
int GetInputInt(File *fp){
int buf;
long size=sizeof(buf);
FileRead((char *)&buf, size, 1, fp);
NeedSwap(fp, &buf, sizeof(buf));
return buf;
}
long GetInputLong(File *fp){
long buf;
long size=sizeof(buf);
FileRead((char *)&buf, size, 1, fp);
NeedSwap(fp, &buf, sizeof(buf));
return buf;
}
unsigned long GetInputULong(File *fp){
unsigned long buf;
long size=sizeof(buf);
FileRead((char *)&buf, size, 1, fp);
NeedSwap(fp, &buf, sizeof(buf));
return buf;
}
float GetInputFloat(File *fp){
float buf;
long size=sizeof(buf);
FileRead((char *)&buf, size, 1, fp);
NeedSwap(fp, &buf, sizeof(buf));
return buf;
}
/*
Note: make sure to use the 8-byte IEEE-compatible short double on the Mac
and not one of the Mac native 80 or 96 bit (10 or 12 byte) formats.
*/
double GetInputDouble(File *fp){
double retval;
#ifdef THINK_C
short double buf; /* IEEE-compatible 8-byte floating point on Mac. */
#else
double buf;
#endif
long size=sizeof(buf);
FileRead((char *)&buf, size, 1, fp);
NeedSwap(fp, &buf, sizeof(buf));
retval=buf; /* Convert to Mac native format. */
return retval;
}
char *GetInputString(char *str, int len, File *fp){
int i, itemsread;
char buf;
long size=sizeof(buf);
for(i=0; i<len && buf && itemsread; i++){
itemsread=FileRead((char *)&buf, size, 1, fp);
*str=buf;
str++;
}
*str='\0';
return str;
}
char *GetInputNString(char *str, int len, File *fp){
int itemsread;
itemsread=FileRead(str, 1, len, fp);
if(str[itemsread-1]!='\0')
str[itemsread]='\0';
return str;
}
/*==================== OUTPUT FUNCTIONS =================*/
// Writes a C string to the output file.
int WriteTxt(File *fp, char *str){
return FWRITE(str, strlen(str), 1, fp);
}
// Writes bytes to a binary output file.
int WriteBin(File *fp, void *buf, int size){
return FWRITE(buf, size, 1, fp);
}
void WriteULong(File *fp, unsigned long x){
unsigned long buf; // copy the data x, it may be a constant
buf=x;
NeedSwap(fp, &buf, sizeof(buf));
WriteBin(fp, &buf, sizeof buf);
}
void WriteLong(File *fp, long x){
long buf;
buf=x;
NeedSwap(fp, &buf, sizeof(buf));
WriteBin(fp, &buf, sizeof buf);
}
void WriteShort(File *fp, signed short x){
signed short buf;
buf=x;
NeedSwap(fp, &buf, sizeof(buf));
WriteBin(fp, &buf, sizeof buf);
}
---------------------------
>From reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
Subject: How to detect whether Debugger is installed?
Date: Mon, 11 Jul 1994 12:10:44 GMT
Organization: Rijksuniversiteit Utrecht
The subject says it all: How do you detect whether MacsBug is present?
I want to know this since I have this FKEY which should activate
MacsBug,
and not do anything when MacsBug is not present. The usual
TrapAvailable
method does not seem to work since
GetTrapAddress( _Unimplemented) == GetTrapAddress( _Debugger)
irrespective of the presence of MacsBug. I also looked up the Gestalt
selectors, and there is one to check whether the Debugger Utilities are
present, but I can't find one to check the presence of the Debugger.
I can think of numerous imperfect ways to check this (comparing first
bytes of _Unimplemented with a copy in my code, checking for MacsBug in
the System Folder, etcetera), but there should be a perfect way.
reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
+++++++++++++++++++++++++++
>From busfield@hurricane.seas.ucla.edu (John D. Busfield)
Date: Wed, 13 Jul 1994 16:14:40 GMT
Organization: School of Engineering & Applied Science, UCLA.
In <1994Jul11.121044.4311@cc.ruu.nl> reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
>The subject says it all: How do you detect whether MacsBug is present?
>I want to know this since I have this FKEY which should activate
>MacsBug,
>and not do anything when MacsBug is not present.
Here's what it says in Macsbug Reference and Debugging Guide pg 412
How MacsBug installs itself.
When a system error or 68000 exception occurs, the ROM code examines
the global variable MacJmp to obtain the address of the debuggers entry
point. MacJmp might contain additional information, depending on whether you
are running under a 24-bit or 32-bit Memory Manager.
If you are running under a 24-bit Memory Manager, the high-order byte
of MacJmp is a flags byte that contains the following information.
Bit Meaning
7 Set if debugger is running
6 Set if debugger can handle system errors
5 Set if debugger is installed
4 Set if debugger can support the Discipline utility
The lower 3 bytes of MacJmp are used to store the address of the debugger's
entry point.
If you are running under a 32-bit Memory Manager, the flags byte is
moved to address $BFF and the long word at MacJmp becomes a full 32-bit
address that points to the debugger's entry point.
So to answer your question, you should only need to look at bit 5 of
the flags byte.
--
- ----------------------------------------------------------------------------
John Busfield | All my realities are virtual
busfield@hurricane.seas.ucla.edu
_____________________________________________________________________________
+++++++++++++++++++++++++++
>From dlamkins@tiac.net (David B. Lamkins)
Date: 17 Jul 1994 00:48:29 GMT
Organization: DBL Systems
In article <1994Jul11.121044.4311@cc.ruu.nl>
reinder@neuretp.biol.ruu.nl (Reinder Verlinde) writes:
> The subject says it all: How do you detect whether MacsBug is present?
The following Pascal unit does everything you need (except give you C
code.) The Apple manual doesn't tell the entire story -- the comments
in the code tell which debuggers and system patches break the rules.
unit DebuggerTest;
interface
type
DebuggerKind = ( {}
debuggerKindNone, {}
debuggerKindMacsBug, {}
debuggerKindTMON, {}
debuggerKindJasik, {}
debuggerKindABZmon, {}
debuggerKindOther {}
);
DebuggerSignature = packed array[1..2] of Char;
{$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
procedure GetDebuggerInfo (var present, active: Boolean; var kind:
DebuggerKind; var signature: DebuggerSignature);
{$ENDC}
{ABZmon can load Òon top ofÓ another debugger. In this case, the
underlying debugger}
{becomes the secondary debugger, but is the only one reported by
GetDebuggerInfo, which}
{looks in the ÒnormalÓ places before trying to find ABZmon. The
ABZMonIsLoaded function}
{can be used to detect ABZmonÕs presence when not the only debugger.}
function ABZMonIsLoaded: Boolean;
function DebuggerPresent: Boolean;
implementation
function ValidDebuggerWorldAddress (p: univ Ptr): Boolean;
begin
{Address must be even and somewhere within addressable RAM or ROM.}
ValidDebuggerWorldAddress := not ODD(ORD(p)) and (ORD(p) >= 0) and
(ORD(p) < ORD(MFTopMem));
end;
type
LongPtr = ^Longint;
IntPtr = ^Integer;
PtrPtr = ^Ptr;
function GetVBR: Ptr;
inline
$7008, {MOVEQ #$EnterSupervisorMode,D0}
$A08D, {_DebugUtil}
$4E7A, $8801, {MOVEC VBR,A0}
$46C0, {MOVE D0,SR ;restore user mode}
$2E88; {MOVE.L A0,(A7)}
function ABZMonIsLoaded: Boolean;
const
_DebugUtil = $A08D;
_Unimplemented = $A89F;
var
VBR: Ptr;
vectorPtr: PtrPtr;
codePtr: LongPtr;
err: OSErr;
begin
{Alain BirtzÕs ABZmon doesnÕt use MacJmp at all. In fact, it doesnÕt
even use}
{the trap dispatcher table. Instead, it patches the trap dispatcher!
The hint for}
{finding this, aside from not finding it anywhere else, is that ABZmon
defines}
{a private trap _DebugNum $AAFF - this has reserved bit 9 set.
ABZmonÕs trap}
{dispatcher can be identified by its first instruction, ORI #$700,SR.
In hex, this}
{is $007C0700.}
if GetOSTrapAddress(_DebugUtil) = GetToolTrapAddress(_Unimplemented)
then
VBR := Ptr(0)
else
begin
if DebuggerGetMax >= 8 then
VBR := GetVBR
else
VBR := Ptr(0);
end;
if ValidDebuggerWorldAddress(VBR) then
begin
vectorPtr := PtrPtr(ORD(VBR) + $28);
codePtr := LongPtr(vectorPtr^);
ABZMonIsLoaded := ValidDebuggerWorldAddress(codePtr) & (codePtr^ =
$007C0700);
end
else
ABZMonIsLoaded := False;
end;
{$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
function NonStandardDebuggerKind (entry: univ Ptr): DebuggerKind;
begin
NonStandardDebuggerKind := debuggerKindOther; {If we canÕt decideÉ}
{JasikÕs ÒThe DebuggerÓ doesnÕt have a world pointer. Its
distinguishing}
{feature is a test for whether it was entered via an F-line trap, by
executing}
{the instruction CMPI #10,DSErrCode. In hex this is $0C7800100AF0.}
if (LongPtr(entry)^ = $0C780010) and (IntPtr(ORD(entry) +
SIZEOF(Longint))^ = $0AF0) then
NonStandardDebuggerKind := debuggerKindJasik
else
{Add other tests as needed.}
;
end;
{$ENDC}
{This is based on info from ÒMacsBug Reference and Debugging Guide for
MacsBug version 6.2Ó}
{The MacsBug reference doesnÕt mention that the ROM debugger
masquerades as a real debugger.}
{Because the ROM debugger doesnÕt have a ÒworldÓ pointer, we have to do
some extra checks.}
procedure GetDebuggerInfo (var present, active: Boolean; var kind:
DebuggerKind; var signature: DebuggerSignature);
const
{The first and current universal ROM is rev 1660. Assume}
{that future universal ROMs will have higher rev numbers.}
UnivROMVersion = 1660;
MacJmp = $120;
Debug32Flags = $BFF;
ROMBase = $2AE;
DebugInstalledFlagBit = 5;
DebugActiveFlagBit = 7;
Megabyte = $100000;
{The following gestalt selectors are from Rene G.A. RosÕ SGSL.}
gestaltEnablerAttr = 'bugy'; {32-bit System Enabler [1.0]}
gestaltEnabler32bit = 7; {32-bit enabler present}
type
PtrPtr = ^Ptr;
IntPtr = ^Integer;
SigPtr = ^DebuggerSignature;
var
err: OSErr;
gestaltResult: Longint;
MM32Bit, univROM, apple32BitEnabler, broken: Boolean;
debugFlagsAddr: Ptr;
debugEntryAddr, debugWorldAddr, ROMBaseAddr: Ptr;
begin
err := Gestalt(gestaltAddressingModeAttr, gestaltResult);
MM32Bit := (err = noErr) & BTST(gestaltResult,
gestalt32BitAddressing);
err := Gestalt(gestaltROMVersion, gestaltResult);
UnivROM := (err = noErr) & (gestaltResult >= UnivROMVersion);
err := Gestalt(gestaltEnablerAttr, gestaltResult);
apple32BitEnabler := (err = noErr) & BTST(gestaltResult,
gestaltEnabler32bit);
{According to the reference, debugger flags are located in the high
byte of}
{MacJmp unless the machine is 32-bit capable, in which case they move
to}
{$BFF. IÕm not sure I believe that the 32-bit enablers (ConnectixÕs
MODE32}
{and AppleÕs 32-bit System Enabler) report the right thing w.r.t.
32-bit capability.}
{Clearly, if the machine is running in 32-bit mode, itÕs 32-bit
capable even under}
{the enablers. But when running under a 32-bit enabler in 24-bit mode,
the enabler}
{would seem to be obliged to report 32-bit capability. In this state,
I wouldnÕt expect}
{the enabler to put up enough of a charade to move the debugger flags
Ñ theyÕd almost}
{certainly end up in the high byte of MacJmp. Also, AppleÕs enabler is
damaged in}
{the opposite case Ñ the debugger traps still look at the high byte of
MacJmp even in}
{32-bit mode. This requires a special test to pretend thereÕs no
debugger present under}
{AppleÕs 32-bit System Enabler in 32-bit addressing mode; 24-bit mode
is OK.}
broken := apple32BitEnabler and MM32Bit;
if not broken then
begin
if MM32Bit or UnivROM then
debugFlagsAddr := Ptr(Debug32Flags)
else
debugFlagsAddr := Ptr(MacJmp);
present := BTST(debugFlagsAddr^, DebugInstalledFlagBit);
active := BTST(debugFlagsAddr^, DebugActiveFlagBit);
end
else
begin
present := False;
active := False;
end;
if present then
begin
debugEntryAddr := StripAddress(PtrPtr(MacJmp)^);
ROMBaseAddr := StripAddress(PtrPtr(ROMBase)^);
if ORD(debugEntryAddr) > ORD(ROMBaseAddr) then {Could be the ROM
debuggerÉ}
if MM32Bit then
begin {In 32-bit mode, any address in or beyond ROM is not in
RAM.}
present := False;
Exit(GetDebuggerInfo);
end
else if ORD(debugEntryAddr) <= ORD(ROMBaseAddr) + Megabyte then
begin {In 24-bit mode, the ROM gets 1MB and can be followed by
RAM.}
present := False;
Exit(GetDebuggerInfo);
end;
{$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
debugWorldAddr := PtrPtr(ORD(debugEntryAddr) - SIZEOF(Ptr))^;
if ValidDebuggerWorldAddress(debugWorldAddr) then
signature := SigPtr(debugWorldAddr)^
else
signature := '??';
case Integer(signature) of
$4D54: {MT}
kind := debuggerKindMacsBug;
{¥ This is from memory; I _think_ TMON registers itself this wayÉ}
$5748: {WH}
kind := debuggerKindTMON;
otherwise
kind := NonStandardDebuggerKind(debugEntryAddr);
end;
{$ENDC}
end
{Alain BirtzÕs ABZmon doesnÕt put anything in MacJmp, but patches the
trap dispatcher.}
else if ABZMonIsLoaded then
begin
kind := debuggerKindABZmon;
{$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
signature := '??';
{$ENDC}
present := True;
end
else {No debugger present.}
begin
kind := debuggerKindNone;
{$IFC (UNDEFINED DebuggerTest_Signature) | DebuggerTest_Signature}
signature := ' ';
{$ENDC}
end;
end;
function DebuggerPresent: Boolean;
var
present, active: Boolean;
kind: DebuggerKind; {this never gets a value}
signature: DebuggerSignature; {this never gets a value}
begin
GetDebuggerInfo(present, active, kind, signature);
DebuggerPresent := present;
end;
end.
Dave
- --
CPU Cycles: Use them now or lose them forever...
---------------------------
>From bb@lightside.com (Bob Bradley)
Subject: Q: Converting PB to FSSpec
Date: Fri, 22 Jul 1994 08:56:47 -0800
Organization: SS Software Inc.
I'm writing an application that needs to process all files/folders in a
folder/disk.
I have this much so far (hasn't been tested) that I've mostly copied &
modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
OSErr FSpProcessDirectoryContents( FSSpec *directory, FSSpecList fileList,
Boolean addDirectories,
Boolean lookInsideDirectories,
Boolean skipOnError )
{
OSErr error = noErr;
CInfoPBRec pb;
short i;
Str63 name;
Boolean keepGoing;
long directoryID;
FSSpec file;
error = FSpGetDirectoryID( directory, &directoryID );
if( error != noErr ) return( error );
pb.hFileInfo.ioCompletion = NULL;
pb.hFileInfo.ioNamePtr = &name[0];
for( i = 1, keepGoing = TRUE; keepGoing; i++ )
{
pb.hFileInfo.ioVRefNum = directory->vRefNum;
pb.hFileInfo.ioDirID = directoryID;
pb.hFileInfo.ioFDirIndex = i;
error = PBGetCatInfoSync( &pb );
if( error == noErr )
{
// Right here I need something to convert the parameter block to
// an FSSpec for this item in the directory. So I can pass it
// my routine that either adds it to the FSSpec List (if it's a
// file) or calls this routine again (if it's a folder).
}
else if( error == fnfErr || !skipOnError )
{
keepGoing = FALSE;
}
}
if( error == fnfErr ) error = noErr;
return( error );
}
Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
FSSpec? or do I need to do some other stuff? Do I need to any special
handling of alias's?
If you find errors in the above routine, I'd like to know about that too.
+++++++++++++++++++++++++++
>From woody@alumni.caltech.edu (William Edward Woody)
Date: 24 Jul 1994 19:37:26 GMT
Organization: California Institute of Technology, Alumni Association
> FSSpec file;
>
> error = FSpGetDirectoryID( directory, &directoryID );
> if( error != noErr ) return( error );
> pb.hFileInfo.ioCompletion = NULL;
> pb.hFileInfo.ioNamePtr = &name[0];
> for( i = 1, keepGoing = TRUE; keepGoing; i++ )
> {
> pb.hFileInfo.ioVRefNum = directory->vRefNum;
> pb.hFileInfo.ioDirID = directoryID;
> pb.hFileInfo.ioFDirIndex = i;
> error = PBGetCatInfoSync( &pb );
> if( error == noErr )
> {
>
> // Right here I need something to convert the parameter block to
> // an FSSpec for this item in the directory. So I can pass it
> // my routine that either adds it to the FSSpec List (if it's a
/*
* Then there's my favorite way to do this
*/
FSMakeFSSpec(directory->vRefNum,directoryID,pb.hFIleInfo.ioNamePtr,&file);
/*
* Or something like that, your milege may vary.
*/
> // file) or calls this routine again (if it's a folder).
>
> }
I hope this helps.
Like Apple says: Don't build the FSSpec by hand yourself. Instead,
use FSMakeFSSpec() [IM VI Ch 25, pg 30] to do the dirty work.
- Bill
--
- William Edward Woody | Disclamer:
woody@alumni.cco.caltech.edu | "He who knows does not speak;
- In Phase Consulting | He who speaks does not know."
337 West California #4; Glendale, CA 91203 | - Lao Tzu
+++++++++++++++++++++++++++
>From mclow@san_marcos.csusm.edu (Marshall Clow)
Date: Sat, 23 Jul 1994 15:40:48 -0800
Organization: Aladdin Systems
In article <bb-2207940856470001@user59.lightside.com>, bb@lightside.com
(Bob Bradley) wrote:
> I'm writing an application that needs to process all files/folders in a
> folder/disk.
>
> I have this much so far (hasn't been tested) that I've mostly copied &
> modified from DragonSmith and DropShell 2.0 to make them work FSSpec's:
>
I always like to see people using DropShell! I will admit to being a
little confused, though. The folder walking code in DropShell uses FSSpecs
already, so I don't know what modifications you need to make.
[ start of included code deleted ]
> error = PBGetCatInfoSync( &pb );
> if( error == noErr )
> {
>
> // Right here I need something to convert the parameter block to
> // an FSSpec for this item in the directory. So I can pass it
> // my routine that either adds it to the FSSpec List (if it's a
> // file) or calls this routine again (if it's a folder).
>
[ end of included code deleted ]
>
> Can I just copy the pb->h.fileParam.ioNamePtr, pb->c.hFileInfo.ioFlParID,
> and pb.hFileInfo.ioVRefNum fields of the parameter block to the the
> FSSpec? or do I need to do some other stuff? Do I need to any special
> handling of alias's?
Well, let's take your q's one at a time.
1) You _can_ just copy the relevant fields of the param block into an
FSSpec, and go from there. This is what the DropShell does, and it will
work. However, Apple has advised against building FSSpecs by hand, and
recomends calling FSMakeFSSpec instead.
2) If you want to resolve alias files while you are walking the file tree,
you can just call ResolveAliasFile () which will do all the alias
traversal for you. _However_, you need to ensure that your loop will
terminate. Imagine the following case:
You have a folder "one"
Inside it is a folder "two"
inside it is a file "three"
and a file "four", which is an alias to "one".
Have fun.
-- Marshall
--
Marshall Clow
Aladdin Systems
mclow@san_marcos.csusm.edu
---------------------------
>From afrancke@netcom.com (Andrew Francke)
Subject: Q: Reentrancy and PowerMac Runtime Model
Date: Mon, 11 Jul 1994 03:13:46 GMT
Organization: Netcom Online Communications Services (408-241-9760 login: guest)
Even after scouring IM:PowerPC System Software, I yet labor under the
thick delusion that there is no way to prevent concurrency/reentrancy
on the PowerMac running native code. Whereas poking the SR worked just
fine before to keep interrupt code from unhappily butting in while
regular code was updating head and tail pointers on lists, there seems
to be no such mention of an equivalent "Critical Section" API on
PowerMac. Yea, verily, I believe it is not possible and am now
contemplating abandoning all Macintosh development. Say it ain't so.
P.S. While you're at it, tell me how it's possible to page-lock an
arbitrary range of memory while running native. Does the VM API
described in IM:Memory still apply? Or is it just, "tough luck --
you'll have to put everything you want in the system heap." Finally,
when (if ever) is the device driver interface going to be revved so
that drivers can be written native? IMHO, this is the dirtiest secret
kept by the Mac rags as device drivers far and away make the machine.
+++++++++++++++++++++++++++
>From rmah@panix.com (Robert Mah)
Date: Mon, 11 Jul 1994 01:04:22 -0500
Organization: One Step Beyond
afrancke@netcom.com (Andrew Francke) wrote:
) Even after scouring IM:PowerPC System Software, I yet labor under the
) thick delusion that there is no way to prevent concurrency/reentrancy
) on the PowerMac running native code. Whereas poking the SR worked just
) fine before to keep interrupt code from unhappily butting in while
) regular code was updating head and tail pointers on lists, there seems
) ...
What an extremely nasty way to check for interupts :-)
I simply use the OS queue routines. Enqueue and Dequeue both disable
interupts so you can be SURE you're VBL's, callbacks and whatnot all
work nicely together.
Cheers,
Rob
_____________________________________________________________________
Robert S. Mah : Macintosh software development : 212.947.6507
One Step Beyond : and network consulting : rmah@panix.com
+++++++++++++++++++++++++++
>From zstern@adobe.com (Zalman Stern)
Date: Mon, 11 Jul 1994 08:26:28 GMT
Organization: Adobe Systems Incorporated
Andrew Francke writes
> Even after scouring IM:PowerPC System Software, I yet labor under the
> thick delusion that there is no way to prevent concurrency/reentrancy
> on the PowerMac running native code. Whereas poking the SR worked just
> fine before to keep interrupt code from unhappily butting in while
> regular code was updating head and tail pointers on lists, there seems
> to be no such mention of an equivalent "Critical Section" API on
> PowerMac. Yea, verily, I believe it is not possible and am now
> contemplating abandoning all Macintosh development. Say it ain't so.
For updating queues in native code, the load-reserved/store-conditional
mechanism is what you want to use. The mnemonics are lwarx and stwcx.
respectively. There are examples on their usage in Appendix G of the MPC601
User's Manual.
> P.S. While you're at it, tell me how it's possible to page-lock an
> arbitrary range of memory while running native. Does the VM API
> described in IM:Memory still apply?
It certainly should. (I.e. I haven't tried this, but I expect there's a
moderate amount of 68k Mac software that would break if things did not work
this way.)
--
Zalman Stern zalman@adobe.com (415) 962 3824
Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
`Wait a second! This is just an octahedron suspended in blue liquid.' - JT
+++++++++++++++++++++++++++
>From mxmora@unix.sri.com (Matthew Xavier Mora)
Date: Mon, 11 Jul 1994 14:32:15 -0700
Organization: SRI International
In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
Francke) wrote:
> on the PowerMac running native code. Whereas poking the SR worked just
> fine before to keep interrupt code from unhappily butting in while
> regular code was updating head and tail pointers on lists, there seems
> to be no such mention of an equivalent "Critical Section" API on
> PowerMac.
This is one thing that they say will die a horrible death in Copland.
Do not set SR!
> you'll have to put everything you want in the system heap." Finally,
> when (if ever) is the device driver interface going to be revved so
> that drivers can be written native? IMHO, this is the dirtiest secret
> kept by the Mac rags as device drivers far and away make the machine.
You'll have to wait for Copland release for the new Native Driver
support. Write them at their Applink address if you want more information.
I don't know the address offhand. Its microkernel.<something>.
Xavier
--
Matt Mora mxmora@unix.sri.com
Testing Neswatcher
+++++++++++++++++++++++++++
>From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
Date: Tue, 12 Jul 1994 10:45:59 +0800
Organization: Department of Computer Science, The University of Western Australia
In article <afranckeCsrAAz.95I@netcom.com>, afrancke@netcom.com (Andrew
Francke) wrote:
>Finally,
>when (if ever) is the device driver interface going to be revved so
>that drivers can be written native? IMHO, this is the dirtiest secret
>kept by the Mac rags as device drivers far and away make the machine.
You can write your drivers native, it's just that you have to have some
68K glue at the front and thereby take a mixed-mode switch on every entry
to them. But even if there was a native API you'd still be taking a
mixed-mode switch because the Device Manager (including the bit that
fields interrupts) is emulated. So if you do a *lot* of work in your
device driver then writing it native would make sense.
All this mess is going to be sorted out in Copland. Which means that a
lot of device drivers are going to have to be rewritten.
--
Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Support HAVOC!"
Department of Computer Science, The University of Western Australia
Who missed that session at WWDC and is desperately seeking the
presentation CD.
+++++++++++++++++++++++++++
>From steele@isi.edu (Craig Steele)
Date: Tue, 12 Jul 1994 12:14:30 -0800
Organization: USC Information Sciences Institute
In article <mxmora-1107941432150001@xavier.sri.com>, mxmora@unix.sri.com
(Matthew Xavier Mora) writes:
> You'll have to wait for Copland release for the new Native Driver
> support. Write them at their Applink address
Judging from the preliminary draft of "Designing PCI Cards and Drivers for
Power Macintosh Computers" that arrived in my mailbox yesterday, bits of the
future are coming a bit sooner. A final PCI Card Developer's Kit for
PowerMacs is said to be scheduled for APDA release in the "summer of 1994."
The PCI runtime drivers use native interfaces. You might be able to get a
copy of the preliminary draft by contacting them at
apple.pci.applelink.apple.com.
Craig S. Steele, steele@isi.edu - Not yet Institutionalized
+++++++++++++++++++++++++++
>From telesis@ecf.toronto.edu (Telesis North)
Date: Wed, 13 Jul 1994 04:19:47 GMT
Organization: telesis north & screen door company
In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
>All this mess is going to be sorted out in Copland. Which means that a
>lot of device drivers are going to have to be rewritten.
Actually, _all_ the device drivers are going to have to be re-written (or
break). That was my favourite quote out of the WWCC,
"Under Copland, (current) 68K device drivers will not run."
Heh.
--
Roger Pantos Telesis North, Inc. telesisnorth
Mac Software Guy telesis@ecf.toronto.edu (AppleLink)
Contrary to popular belief, green eggs & ham suck big time.
+++++++++++++++++++++++++++
>From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
Date: Thu, 14 Jul 1994 11:20:10 +0800
Organization: Department of Computer Science, The University of Western Australia
In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
North) wrote:
>In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
>Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
>>All this mess is going to be sorted out in Copland. Which means that a
>>lot of device drivers are going to have to be rewritten.
>
>Actually, _all_ the device drivers are going to have to be re-written (or
>break). That was my favourite quote out of the WWCC,
>
> "Under Copland, (current) 68K device drivers will not run."
Well this is an interesting question. I didn't catch that session at WWDC
but I can see no reason why software only device drivers (such .Notify and
.Reminder) couldn't be supported. These are just using the Device Manager
as a kludgy share library system that gives you non-interrupt time. So
was there any comment about non-hardware device drivers?
>Roger Pantos
Hi Roger! Maybe if your real name was something other that Telesis North
I'd catch your postings more often (:
--
Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Support HAVOC!"
Department of Computer Science, The University of Western Australia
+++++++++++++++++++++++++++
>From rang@winternet.com (Anton Rang)
Date: 14 Jul 1994 04:24:00 GMT
Organization: Trillium Research, Inc.
In article <afranckeCsrAAz.95I@netcom.com> afrancke@netcom.com (Andrew Francke) writes:
>Even after scouring IM:PowerPC System Software, I yet labor under the
>thick delusion that there is no way to prevent concurrency/reentrancy
>on the PowerMac running native code.
You're right! Well, more or less. You can change the SR by going
back into 68K code, and since all interrupts are currently dispatched
through the emulator, this will block them from being processed until
you change the SR back. But (a) this will break, and (b) this will be
incredibly slow. Don't do it if you don't have to.
>Whereas poking the SR worked just
>fine before to keep interrupt code from unhappily butting in while
>regular code was updating head and tail pointers on lists
Well, in this case you can either (a) call Enqueue/Dequeue, which is
slow because of the mode switch but will be atomic, or (b) use a
little assembly language to call the lwarx/stwcx instructions. Check
your manual for details.
>there seems to be no such mention of an equivalent "Critical Section"
>API on PowerMac.
There will be. Unfortunately, it's not there yet. The hardware is
ahead of the software, currently.
>P.S. While you're at it, tell me how it's possible to page-lock an
>arbitrary range of memory while running native. Does the VM API
>described in IM:Memory still apply?
Yes, that API still works. (All the current APIs work, actually.)
>Finally, when (if ever) is the device driver interface going to be
>revved so that drivers can be written native?
With the release of PCI-based Macintoshes, at first, and then with
the next major system release (for older PowerMacs too presumably). I
wish it were sooner, I *hate* debugging my current driver. :)
--
Anton Rang (rang@winternet.com)
+++++++++++++++++++++++++++
>From telesis@ecf.toronto.edu (Telesis North)
Date: Thu, 14 Jul 1994 04:47:49 GMT
Organization: Roger @ Telesis North
In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
>
>Well this is an interesting question. I didn't catch that session at WWDC
>but I can see no reason why software only device drivers (such .Notify and
>.Reminder) couldn't be supported. These are just using the Device Manager
>as a kludgy share library system that gives you non-interrupt time. So
>was there any comment about non-hardware device drivers?
I don't remember any; I just remember the speaker (Russell?) being
pretty blunt about it. My understanding is that they're planning on
ripping out the entire toolbox-level I/O architecture, along with
the 68K-centric interrupt services, and heaving it off the dock with
a huge sigh of relief. (It will of course be replaced with a spiffy
new re-entrant driver model with a message-passing interface to the
microkernel that will make life wonderful for everyone, once they've
re-written their drivers.)
I agree with your point, though. I'd say an easy 50% of the drivers
running on my machine are just there to provide user interface hacks
(or other software-only goodies). Come to think of it, it's probably
mostly intercine warfare between the Now Utilities and everyone else...
The problem is that most of these are so skanky, I'm not sure how far
you'd have to go, emulation-wise, to get any level of backward
compatibility.
I suppose that one could write an early-load INIT that patched
OpenDriver(), GetDCtlEntry() and friends, and used a faceless
background app to provide non-interrupt time to the drivers in
the custom entry table, but you'd still have people looking
for familiar things in the global Unit Table in the Toolbox
space, not to mention making asynchronous PBControl calls with
oddball semantics... I shudder even to think about it. :-)
Copland is going to break a lot of software, in the name of
performance. Not necessarily straight-line application software,
but lots of stand-alone gadgets and integrated systems. (Anyone
holding out any hope for FaxSTF?)
Should Apple devote engineer and QA time to emulating the old driver
model? Tough question. I know I'm not going to - I'm going to re-write
our drivers (and turn them into processes, most likely).
>Hi Roger! Maybe if your real name was something other that Telesis North
>I'd catch your postings more often (:
Yeah, yeah. :-) I still get my news fix through an ancient Unix shell
account that we pay a university through the nose for. I'm thinking that
the time I could spend reading through the man pages might be better
spent pestering people to get my Mac IP-connected. (Still, beats
chipping out TCP packets on stone tablets, which is what we did in the
old days...)
--
Roger Pantos Telesis North, Inc. telesisnorth
Mac Software Guy telesis@ecf.toronto.edu (AppleLink)
I can think of nothing more odious than a philosophy that forces its
beliefs or its conscriptions on those who are unwilling or uninterested
in having them.
+++++++++++++++++++++++++++
>From chewey@nesw.mv.com (Matthew E. Axsom)
Date: Fri, 15 Jul 1994 13:30:42 GMT
Organization: New England Software Works
In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
> In article <Csv2oz.KKK@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
> North) wrote:
>
> >In article <quinn-1207941045590001@edu-dynamic1.educ.ecel.uwa.edu.au>,
> >Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
> >>All this mess is going to be sorted out in Copland. Which means that a
> >>lot of device drivers are going to have to be rewritten.
> >
> >Actually, _all_ the device drivers are going to have to be re-written (or
> >break). That was my favourite quote out of the WWCC,
> >
> > "Under Copland, (current) 68K device drivers will not run."
>
> Well this is an interesting question. I didn't catch that session at WWDC
> but I can see no reason why software only device drivers (such .Notify and
> .Reminder) couldn't be supported. These are just using the Device Manager
> as a kludgy share library system that gives you non-interrupt time. So
> was there any comment about non-hardware device drivers?
>
I believe that they used that as a blanket statement at first and later
backed away from that and said that the current driver model would still
run as long as it was a "softwre driver" (e.g. .Reminder or .Notify) and
not a "hardware driver". I believe they said that as long as it doesn't
touch the hardware directly, the old drivers could still be used.
-Chewey
struct Matthew: E, Axsom { //chewey@nesw.mv.com
Matthew(void) : E(), Axsom() {}
Boolean macSoftwareEngineer(long future) {return future==Random();}
Boolean newEnglandSoftwareWorks(StringPtr name) {return true;}
};
+++++++++++++++++++++++++++
>From absurd@apple.com (Tim Dierks)
Date: Fri, 22 Jul 1994 23:27:05 GMT
Organization: Apple Computer, Inc.
In article <Cswynq.Bx1@ecf.toronto.edu>, telesis@ecf.toronto.edu (Telesis
North) wrote:
> In article <quinn-1407941120100001@edu-dynamic1.educ.ecel.uwa.edu.au>,
> Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> wrote:
> >
> >Well this is an interesting question. I didn't catch that session at WWDC
> >but I can see no reason why software only device drivers (such .Notify and
> >.Reminder) couldn't be supported. These are just using the Device Manager
> >as a kludgy share library system that gives you non-interrupt time. So
> >was there any comment about non-hardware device drivers?
>
> I don't remember any; I just remember the speaker (Russell?) being
> pretty blunt about it. My understanding is that they're planning on
> ripping out the entire toolbox-level I/O architecture, along with
> the 68K-centric interrupt services, and heaving it off the dock with
> a huge sigh of relief. (It will of course be replaced with a spiffy
> new re-entrant driver model with a message-passing interface to the
> microkernel that will make life wonderful for everyone, once they've
> re-written their drivers.)
>
> I agree with your point, though. I'd say an easy 50% of the drivers
> running on my machine are just there to provide user interface hacks
> (or other software-only goodies). Come to think of it, it's probably
> mostly intercine warfare between the Now Utilities and everyone else...
>
> The problem is that most of these are so skanky, I'm not sure how far
> you'd have to go, emulation-wise, to get any level of backward
> compatibility.
Copland will support the Device manager driver model for dispatching to
old-style drivers; this level of compatibility should allow many drivers
to continue to work, especially those which are software-only, and just
manipulate data or dispatch to other drivers or toolboxes. Of course, this
doesn't guarantee the software inside the driver will still work
(depending on its assumptions), but we'll try to support the mechanism as
best we can. 68K drivers which touch hardware or which get invoked to
handle hardware interrupts will most likely not be compatible.
> Copland is going to break a lot of software, in the name of
> performance. Not necessarily straight-line application software,
> but lots of stand-alone gadgets and integrated systems. (Anyone
> holding out any hope for FaxSTF?)
>
> Should Apple devote engineer and QA time to emulating the old driver
> model? Tough question. I know I'm not going to - I'm going to re-write
> our drivers (and turn them into processes, most likely).
Copland won't be 100% compatible, but a lot of the stuff we break we'll
break because it's fundamentally incompatible with progress; stuff that's
bad, but not that bad, we'll just have to see...
> Roger Pantos Telesis North, Inc. telesisnorth
--
Tim Dierks
absurd@apple.com
---------------------------
>From stk@uropax.contrib.de (Stefan Kurth)
Subject: Std filter proc trashes register D3!
Date: 18 Jul 1994 14:40:50 +0200
Organization: Contributed Software GbR
Just discovered another system software bug: the standard filter proc
(the one that you get with GetStdFilterProc() ) distroys the contents
of the D3 register. Took me quite some time to figure out why one my
variables kept changing all by itself...
Is this a known bug? If not, how do I go about reporting it to Apple?
________________________________________________________________________
Stefan Kurth Berlin, Germany stk@contrib.de
+++++++++++++++++++++++++++
>From D.A.G.Gillies@bradford.ac.uk (David Gillies)
Date: Mon, 18 Jul 1994 15:13:25 GMT
Organization: Unseen University, Ankh-Morpork
In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de (Stefan Kurth) writes:
>Just discovered another system software bug: the standard filter proc
>(the one that you get with GetStdFilterProc() ) distroys the contents
>of the D3 register. Took me quite some time to figure out why one my
>variables kept changing all by itself...
>
>Is this a known bug? If not, how do I go about reporting it to Apple?
>
This definitely sounds like a bug. If nothing else, the compiler should make
callbacks safe by padding where necessary with MOVEM. It's only D0-D2 and
A0/A1 that routines are meant to be allowed to stamp on, and compilers
should recognize this and guard against it. I might be wrong, but this does
seem suspicious.
Personally I hate the standard filter proc, but I always prefer to roll my own.
______________________________________________________________________
David A. G. Gillies (D.A.G.Gillies@bradford.ac.uk)
University of Bradford, Bradford, West Yorkshire, England
(c) 1994 Wittgenstein and The Furniture Depository of The Living Dead
A little learning is a dangerous thing - but not half as dangerous as a
lot of ignorance.
- ---------------------REPLIES VIA EMAIL PLEASE-----------------------
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
+++++++++++++++++++++++++++
>From stk@uropax.contrib.de (Stefan Kurth)
Date: 19 Jul 1994 01:16:49 +0200
Organization: Contributed Software GbR
In article <1994Jul18.151325.8525@bradford.ac.uk>,
David Gillies <D.A.G.Gillies@bradford.ac.uk> wrote:
> In article <30dt8i$32d@uropax.contrib.de> stk@uropax.contrib.de
> (Stefan Kurth) writes:
>
> > Is this a known bug? If not, how do I go about reporting it to Apple?
>
> This definitely sounds like a bug.
Sure it is - my question was if it is a _known_ bug... :-)
> If nothing else, the compiler should make callbacks safe by padding where
> necessary with MOVEM. It's only D0-D2 and A0/A1 that routines are meant
> to be allowed to stamp on, and compilers should recognize this and guard
> against it.
In this case it's not the compiler's job to save registers (I mean, not _my_
compiler's; it would have been the job of whatever compiler Apple used to
compile their system software). The standard filter proc should save the
registers that it uses; however, it saves only D4-D7, but also uses D3.
> Personally I hate the standard filter proc, but I always prefer to roll
> my own.
Would you explain why? I have found it extremely handy. It does a lot of
work for you.
________________________________________________________________________
Stefan Kurth Berlin, Germany stk@contrib.de
+++++++++++++++++++++++++++
>From Alexander M. Rosenberg <alexr@apple.com>
Date: Tue, 19 Jul 1994 02:20:19 GMT
Organization: Hackers Anonymous
In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth, stk@uropax.contrib.de
writes:
> Just discovered another system software bug: the standard filter proc
> (the one that you get with GetStdFilterProc() ) distroys the contents
> of the D3 register. Took me quite some time to figure out why one my
> variables kept changing all by itself...
>
> Is this a known bug? If not, how do I go about reporting it to Apple?
Yes. Thank you for taking the time to track it down. I believe that it is
under consideration for our next System Update release.
- -------------------------------------------------------------------------
- Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne -
- 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion -
- Palo Alto, CA 94301 - - Systems -
- (415) 329-8463 - Nobody is my employer so - :-) -
- - nobody cares what I say. - -
+++++++++++++++++++++++++++
>From David A Lyons <dlyons@apple.com>
Date: Tue, 19 Jul 1994 06:00:07 GMT
Organization: Apple Computer, Inc.
In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
stk@uropax.contrib.de writes:
> Just discovered another system software bug: the standard filter proc
> (the one that you get with GetStdFilterProc() ) distroys the contents
> of the D3 register. Took me quite some time to figure out why one my
> variables kept changing all by itself...
>
> Is this a known bug? If not, how do I go about reporting it to Apple?
It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
you'll have to work around it in your application.
Dave Lyons
Mr Tangent
+++++++++++++++++++++++++++
>From jonasw@lysator.liu.se (Jonas Wallden)
Date: 19 Jul 1994 16:59:31 GMT
Organization: (none)
David A Lyons <dlyons@apple.com> writes:
>In article <30dt8i$32d@uropax.contrib.de> Stefan Kurth,
>stk@uropax.contrib.de writes:
>> Just discovered another system software bug: the standard filter proc
>> (the one that you get with GetStdFilterProc() ) distroys the contents
>> of the D3 register. Took me quite some time to figure out why one my
>> variables kept changing all by itself...
>>
>> Is this a known bug? If not, how do I go about reporting it to Apple?
>
>It's a known bug in ROMs earlier than the Quadra 840av/660av; for now
>you'll have to work around it in your application.
>
>Dave Lyons
>Mr Tangent
On a related subject: I installed a memory grow proc in an application that
uses a small heap, and that also uses StandardFile to select folders. I
noticed that my grow proc was called while the SF dialog was being shown,
and that SF tried to allocate a large memory block (size > 64 Kb). Of course
it failed to find the free memory but everything works ok anyway.
Is this just some cache memory that it tries to allocate for the fancy
color icons used by Hardware System Update 3.0? I will have to check again
to make sure it's not one of my system extensions playing a trick on me.
-- Jonas Wallden
--
-- Jonas Wallden -- Internet: jonasw@lysator.liu.se -- AppleLink: sw1369 --
+++++++++++++++++++++++++++
>From dean@genmagic.com (Dean Yu)
Date: 19 Jul 1994 18:35:23 GMT
Organization: General Magic, Inc.
In article <30dt8i$32d@uropax.contrib.de>, stk@uropax.contrib.de (Stefan
Kurth) wrote:
> Just discovered another system software bug: the standard filter proc
> (the one that you get with GetStdFilterProc() ) distroys the contents
> of the D3 register. Took me quite some time to figure out why one my
> variables kept changing all by itself...
>
> Is this a known bug? If not, how do I go about reporting it to Apple?
This is a known bug. (Well, I knew about it when I was there...) I seem
to remember writing some inline code to work around this problem, but I
don't remember what that was for.
-- Dean Yu
Negative Ethnic Role Model
General Magic, Inc.
---------------------------
>From Jim Conner <jc30@cornell.edu>
Subject: Which NIM for serial port info?
Date: 25 Jul 1994 02:13:58 GMT
Organization: Cornell University
Hello,
I have been developing a somewhat specialized application for analysis of
data generated by an instrument in our lab. Currently, the data is taken
from the instrument's small display unit and entered by hand into the
application. The data is also available from the instrument's RS-232
port. The hope is that this data can be sent directly from the
instrument to the Mac by way of one of the Mac's serial ports.
I think that I have a grip on the hardware aspect of this connection
(wiring one of the Mac's RS-422 serial ports so it looks like RS-232, and
making the correct cable to the instrument). I would like to know,
though, (1) which New Inside Macintosh book covers serial port
manipulations, and (2) if anyone has any other references that have been
helpful with this sort of problem.
Thanks,
Jim Conner
+++++++++++++++++++++++++++
>From bierman@caelab1.cae.wisc.edu (Peter Bierman)
Date: Sun, 24 Jul 1994 23:43:13 -0500
Organization: The Metropolis BBS <614/846-1911> Info-Mac on CD!
In article <30v756$ghq@newsstand.cit.cornell.edu>, Jim Conner
<jc30@cornell.edu> wrote:
> I would like to know,
> though, (1) which New Inside Macintosh book covers serial port
> manipulations, and (2) if anyone has any other references that have been
> helpful with this sort of problem.
>
NIM: Devices. (I don't even know if it's out yet) Chapter 5.
Many people suggest "Terminal 2.2" as a great source for example code, in C.
-Peter
--
Peter Bierman |"Sometimes I think that the surest sign
bierman@caelab1.cae.wisc.edu | that intelligent life exists elsewhere
The Metropolis 614/846-1911 | in the universe is that none of it has
600+MB, 2CDs, 2Lines@14.4 | tried to contact us." --Calvin
---------------------------
End of C.S.M.P. Digest
**********************